您好,登錄后才能下訂單哦!
這篇文章主要介紹“vue組件中data為什么是函數”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“vue組件中data為什么是函數”文章能幫助大家解決問題。
原因:防止多個組件實例對象之間共用一個data,產生數據污染;采用函數的形式,initData時會將其作為工廠函數都會返回全新data對象。當將組件中的data寫成一個函數,數據以函數返回值形式定義,這樣每復用一次組件,就會返回一份新的data,擁有自己的作用域,類似于給每個組件實例創建一個私有的數據空間,讓各個組件實例維護各自的數據。
一、實例和組件定義data的區別
vue實例的時候定義data屬性既可以是一個對象,也可以是一個函數
const app = new Vue({
el:"#app",
// 對象格式
data:{
foo:"foo"
},
// 函數格式
data(){
return {
foo:"foo"
}
}
})
組件中定義data屬性,只能是一個函數
如果為組件data直接定義為一個對象
Vue.component('component1',{
template:`<div>組件</div>`,
data:{
foo:"foo"
}})
則會得到警告信息
警告說明:返回的data應該是一個函數在每一個組件實例中
二、組件data定義函數與對象的區別
上面講到組件data必須是一個函數,不知道大家有沒有思考過這是為什么呢?
在我們定義好一個組件的時候,vue最終都會通過Vue.extend()構成組件實例
這里我們模仿組件構造函數,定義data屬性,采用對象的形式
function Component(){
}
Component.prototype.data = {
count : 0
}
創建兩個組件實例
const componentA = new Component()
const componentB = new Component()
修改componentA組件data屬性的值,componentB中的值也發生了改變
console.log(componentB.data.count) // 0
componentA.data.count = 1
console.log(componentB.data.count) // 1
產生這樣的原因這是兩者共用了同一個內存地址,componentA修改的內容,同樣對componentB產生了影響。【學習視頻分享:vue視頻教程、web前端視頻】
如果我們采用函數的形式,則不會出現這種情況(函數返回的對象內存地址并不相同)
function Component(){
this.data = this.data()
}
Component.prototype.data = function (){
return {
count : 0
}
}
修改componentA組件data屬性的值,componentB中的值不受影響
console.log(componentB.data.count) // 0
componentA.data.count = 1
console.log(componentB.data.count) // 0
vue組件可能會有很多個實例,采用函數返回一個全新data形式,使每個實例對象的數據不會受到其他實例對象數據的污染
三、原理分析
首先可以看看vue初始化data的代碼,data的定義可以是函數也可以是對象
源碼位置:/vue-dev/src/core/instance/state.js
function initData (vm: Component) {
let data = vm.$options.data
data = vm._data = typeof data === 'function'
? getData(data, vm)
: data || {}
...
}
data既能是object也能是function,那為什么還會出現上文警告呢?
別急,繼續看下文
組件在創建的時候,會進行選項的合并
源碼位置:/vue-dev/src/core/util/options.js
自定義組件會進入mergeOptions進行選項合并
Vue.prototype._init = function (options?: Object) {
...
// merge options
if (options && options._isComponent) {
// optimize internal component instantiation
// since dynamic options merging is pretty slow, and none of the
// internal component options needs special treatment.
initInternalComponent(vm, options)
} else {
vm.$options = mergeOptions(
resolveConstructorOptions(vm.constructor),
options || {},
vm
)
}
...
}
定義data會進行數據校驗
源碼位置:/vue-dev/src/core/instance/init.js
這時候vm實例為undefined,進入if判斷,若data類型不是function,則出現警告提示
strats.data = function (
parentVal: any,
childVal: any,
vm?: Component
): ?Function {
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);
};
關于“vue組件中data為什么是函數”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。