為什么vue中data必須是一個函數(shù)
類比引用數(shù)據(jù)類型
Object是引用數(shù)據(jù)類型,如果不用function 返回,每個組件的data 都是內(nèi)存的同一個地址,一個數(shù)據(jù)改變了其他也改變了;
javascipt只有函數(shù)構(gòu)成作用域(注意理解作用域,只有函數(shù)的{}構(gòu)成作用域,對象的{}以及if(){}都不構(gòu)成作用域)瓷患,data是一個函數(shù)時骡尽,每個組件實(shí)例都有自己的作用域,每個實(shí)例相互獨(dú)立,不會相互影響
如果 data 是個對象擅编,那么整個vue實(shí)例將共享一份數(shù)據(jù)攀细,也就是各個組件實(shí)例間可以隨意修改其他組件的任意值,這就有坑了【原型繼承的槽點(diǎn):指向相同爱态,所有實(shí)例都會改變】谭贪。
- 但是 data 定義成一個函數(shù),將會 return 出一個唯一的對象锦担,不會和其他組件共享一個對象俭识。
我們注冊組件的時候?qū)嶋H上是建立了一個組件構(gòu)造器的引用,只有使用組件的時候才會真正創(chuàng)建一個組件實(shí)例洞渔。
- 指向同一個對象/屬性問題
function Person () {}
Person.prototype.data = {
a:1,
b:2
}
let p1 = new Person();
let p2 = new Person();
p1.data.a= 'A';
console.log(p2.data.a); // 'A'
- 解決:每一個實(shí)例化Vue組件對象下都有一個單獨(dú)的data方法
function Person2 () {
this.data = this.data();
}
Person2.prototype.data = function () {
return {
a: 1,
b: 2
}
}
let p4 = new Person2();
let p5 = new Person2();
p4.data.a = 'A';
console.log(p5.data.a); // 1
Vue源碼:
function initData (vm: Component) {
let data = vm.$options.data
data = vm._data = typeof data === 'function' ? getData(data, vm): data || {}
}
export function getData (data: Function, vm: Component): any {
pushTarget()
try {
return data.call(vm, vm)
} catch (e) {
handleError(e, vm, `data()`)
return {}
} finally {
popTarget()
}
}