vue中定義的data為什么是函數(shù)
高頻面試題:
vue中的data為啥是函數(shù)?
答案是:是不是一定是函數(shù),得看場景。并且,也無需擔(dān)心什么時(shí)候該將data寫為函數(shù)還是對象,因?yàn)?code>vue內(nèi)部已經(jīng)做了處理,并在控制臺(tái)輸出錯(cuò)誤信息。
一、new Vue場景
new Vue({
el: "#app",
// 方式一:對象
data: {
obj: {
name: "qb",
}
},
// 方式二:工廠函數(shù)
// data () {
// return {
// obj: {
// name: "qb",
// }
// }
// },
template: `<div>{{obj.name}}</div>`
});這種場景主要為項(xiàng)目入口或者多個(gè)html頁面各實(shí)例化一個(gè)Vue時(shí),這里的data即可用對象的形式,也可用工廠函數(shù)返回對象的形式。因?yàn)?,這里的data只會(huì)出現(xiàn)一次,不存在重復(fù)引用而引起的數(shù)據(jù)污染問題。
二、組件場景
Vue.component("countComponent", {
data() {
return {
count: 1
};
},
template: `<div>
<button @click='changeCount'>遞增</button>
<span>{{count}}</span>
</div>`,
methods: {
changeCount() {
this.count++;
}
}
});
new Vue({
el: "#app",
template: `<div>
<countComponent></countComponent>
<countComponent></countComponent>
</div>`
});首先定義全局組件countComponent,然后將該組件重復(fù)使用兩次,當(dāng)定義全局組件的時(shí)候,會(huì)執(zhí)行Vue的component方法:
// ASSET_TYPES定義在文件shared/constants.js文件中
export const ASSET_TYPES = [
'component',
'directive',
'filter'
]
// 以下ASSET_TYPES遍歷綁定方法的定義在initGlobalAPI(Vue)全局方法掛載階段完成
import { ASSET_TYPES } from 'shared/constants'
import { isPlainObject, validateComponentName } from '../util/index'
export function initAssetRegisters (Vue: GlobalAPI) {
/**
* Create asset registration methods.
*/
ASSET_TYPES.forEach(type => {
Vue[type] = function (
id: string,
definition: Function | Object
): Function | Object | void {
if (!definition) {
return this.options[type + 's'][id]
} else {
/* istanbul ignore if */
if (process.env.NODE_ENV !== 'production' && type === 'component') {
validateComponentName(id)
}
if (type === 'component' && isPlainObject(definition)) {
definition.name = definition.name || id
definition = this.options._base.extend(definition)
}
if (type === 'directive' && typeof definition === 'function') {
definition = { bind: definition, update: definition }
}
this.options[type + 's'][id] = definition
return definition
}
}
})
}這里的場景是component,那么會(huì)執(zhí)行到definition = this.options._base.extend(definition)進(jìn)行組件構(gòu)造函數(shù)的實(shí)現(xiàn),這里的this.options._base就是構(gòu)造函數(shù)Vue,extend方法為:
// Vue.extend 方法的定義在initGlobalAPI(Vue)全局方法掛載階段完成
export function initExtend (Vue: GlobalAPI) {
Vue.extend = function (extendOptions: Object): Function {
extendOptions = extendOptions || {}
const Super = this
const SuperId = Super.cid
const cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {})
if (cachedCtors[SuperId]) {
return cachedCtors[SuperId]
}
const name = extendOptions.name || Super.options.name
if (process.env.NODE_ENV !== 'production' && name) {
validateComponentName(name)
}
const Sub = function VueComponent (options) {
this._init(options)
}
Sub.prototype = Object.create(Super.prototype)
Sub.prototype.constructor = Sub
Sub.cid = cid++
Sub.options = mergeOptions(
Super.options,
extendOptions
)
// ...
}
}定義完組件構(gòu)造函數(shù)Sub后,在為其合并options時(shí),會(huì)執(zhí)行到mergeOptions:
/**
* Merge two option objects into a new one.
* Core utility used in both instantiation and inheritance.
*/
export function mergeOptions (
parent: Object,
child: Object,
vm?: Component
): Object {
// ...
const options = {}
let key
for (key in parent) {
mergeField(key)
}
for (key in child) {
if (!hasOwn(parent, key)) {
mergeField(key)
}
}
function mergeField (key) {
const strat = strats[key] || defaultStrat
options[key] = strat(parent[key], child[key], vm, key)
}
return options
}在當(dāng)前例子中,會(huì)通過const options = {}定義一個(gè)空對象,然后分別將parent和child上的屬性合并到options上,此時(shí)data的合并策略為:
strats.data = function (
parentVal,
childVal,
vm
) {
if (!vm) {
if (childVal && typeof childVal !== 'function') {
process.env.NODE_ENV !== 'production' && warn(
'The "data" option should be a function ' +
'that returns a per-instance value in component ' +
'definitions.',
vm
);
return parentVal
}
return mergeDataOrFn(parentVal, childVal)
}
return mergeDataOrFn(parentVal, childVal, vm)
};這里childVal類型為object,即typeof childVal !== 'function'成立,進(jìn)而在開發(fā)環(huán)境會(huì)在控制臺(tái)輸出警告并且直接返回parentVal,說明這里壓根就沒有把childVal中的任何data信息合并到options中去。
總結(jié)
vue中已經(jīng)幫我們控制臺(tái)輸出警告,并且不會(huì)讓組件中的data合并到options中去,那么,很友好的處理了開發(fā)者的強(qiáng)行將data寫成對象的可能性。
到此這篇關(guān)于vue中定義的data為什么是函數(shù)的文章就介紹到這了,更多相關(guān)vue中data為什么是函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue實(shí)現(xiàn)網(wǎng)易云音樂純界面
這篇文章主要為大家介紹了vue實(shí)現(xiàn)網(wǎng)易云音樂純界面過程詳解,附含詳細(xì)源碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
基于Vue中this.$options.data()的this指向問題
這篇文章主要介紹了基于Vue中this.$options.data()的this指向問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
vue2.0如何實(shí)現(xiàn)echarts餅圖(pie)效果展示
這篇文章主要介紹了vue2.0如何實(shí)現(xiàn)echarts餅圖(pie)效果展示,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10
vue+element實(shí)現(xiàn)下拉菜單并帶本地搜索功能示例詳解
這篇文章主要介紹了vue+element實(shí)現(xiàn)下拉菜單并帶本地搜索功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09

