在建立或註冊模板的時候,傳入一個data屬性作為用來繫結的資料。但是在元件中,data必須是一個函式,而不能直接把一個物件賦值給它。
Vue.component('my-component', {
template: '<div>OK</div>',
data() {
return {} // 返回一個唯一的物件,不要和其他元件共用一個物件進行返回
},
})複製程式碼
你在前面看到,在new Vue()的時候,是可以給data直接賦值為一個物件的。這是怎麼回事,為什麼到了元件這裡就不行了。
你要理解,上面這個操作是一個簡易操作,實際上,它首先需要建立一個元件構造器,然後註冊元件。註冊元件的本質其實就是建立一個元件構造器的引用。使用元件才是真正建立一個元件例項。所以,註冊元件其實並不產生新的元件類,但會產生一個可以用來例項化的新方式。
理解這點之後,再理解js的原型鏈:
var MyComponent = function() {}
MyComponent.prototype.data = {
a: 1,
b: 2,
}
// 上面是一個虛擬的元件構造器,真實的元件構造器方法很多
var component1 = new MyComponent()
var component2 = new MyComponent()
// 上面例項化出來兩個元件例項,也就是通過<my-component>呼叫,建立的兩個例項
component1.data.a === component2.data.a // true
component1.data.b = 5
component2.data.b // 5複製程式碼
可以看到上面程式碼中最後三句,這就比較坑爹了,如果兩個例項同時引用一個物件,那麼當你修改其中一個屬性的時候,另外一個例項也會跟著改。這怎麼可以,兩個例項應該有自己各自的域才對。所以,需要通過下面方法來進行處理:
var MyComponent = function() {
this.data = this.data()
}
MyComponent.prototype.data = function() {
return {
a: 1,
b: 2,
}
}複製程式碼
var MyComponent = function() {
this.data = this.data()
}
MyComponent.prototype.data = function() {
return {
a: 1,
b: 2,
}
}
function () {
return {
a: 1,
b: 2,
}
}
var component1 = new MyComponent()
var component2 = new MyComponent()
undefined
component1.data===component2.data
false
component1.data
Object {a: 1, b: 2} 複製程式碼
這樣每一個例項的data屬性都是獨立的,不會相互影響了。所以,你現在知道為什麼vue元件的data必須是函式了吧。這都是因為js本身的特性帶來的,跟vue本身設計無關。其實vue不應該把這個方法名取為data(),應該叫setData或其他更容易立即的方法名。