由淺入深瞭解Vue組件中的data| 8月更文挑戰

咱們先參考vue官網給出的解釋:vue

一個組件的 data 選項必須是一個函數使得每一個實例能夠維護一份被返回對象的獨立的拷貝api

首先,咱們先看一個簡單的原型鏈有關知識。markdown

`function VueComponent(){} 

VueComponent.prototype.$options = { 
        data:{
                name:'zf',
        }
}

let vc1 = new VueComponent()

vc1.$options.data = 'lx'

let vc2 = new VueComponent() 

console.log(vc2.$options.data)` 
複製代碼

咱們能夠看到,實例對象VC1修改了name的值爲「lx」,新的實例對象VC2訪問到的值也是修改後的「lx」。函數

這是由於VC1和VC2兩個實例對象在操做$options時是在操做VueComponent構造函數原型對象上的屬性,實例對象的隱式原型屬性等於其構造函數的顯示原型屬性,因此它們指向的是同一塊內存空間。 這致使了兩個對象數據不獨立,會相互污染。spa

根據以上結果,再回到咱們Vue組件中的data屬性。prototype

同一個組件被複用屢次,會建立多個實例。這些實例用的是同一個構造函數,若是 data 是一個對象的話,那麼全部組件都共享了同一個對象。爲了保證組件的數據獨立性要求每一個組件必須經過 data 函數返回一個對象做爲組件的狀態。code

core/global-api/extend.js line:33component

Sub.options = mergeOptions(Super.options, extendOptions)

function mergeOptions() {
        function mergeField(key) {
                const strat = strats[key] || defaultStrat options[key] = strat(parent[key], child[key], vm, key)
        }
}
strats.data = function(parentVal: any, childVal: any, vm ? : Component

): ? Function {
        if (!vm) { // 合併是會判斷子類的data必須是一個函數 
                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)
}
複製代碼
總結:

一個組件被使用屢次,用的都是同一個構造函數。爲了保證組件的不一樣的實例data不衝突,組件中的數據相互 獨立,要求data必須是一個函數,這樣組件間不會相互影響。orm

相關文章
相關標籤/搜索