在 Vue中,定義data時,經常有好幾種寫法,一不小心會混淆,這裏徹底詳述一下,以便記分清 。
一、在vue中,定義data可以有三種寫法。
1. 第一種寫法,data是一個對象。
var app = new Vue({
el: '#app',
data: {
mess: 'aerchi'
}
})
2. 第二種寫法,data是一個函數。
var app = new Vue({
el: '#app',
data: function() {
return {
mess: 'aerchi'
}
}
})
3. 第三種寫法,data是一個函數,是第二種寫法的ES6寫法。
var app = new Vue({
el: '#app',
data() {
return {
mess: 'aerchi'
}
}
})
二、在Vue實例及組件中定義 data的形式。
1. 在Vue 實例中可以這樣定義 data, 兩種定義方法均生效。
//Vue中定義的data可以是 object 也可以是函數,效果相同。驗證 2020-3-7
new Vue({
// data () {
// return {
// message: 'message-data() function!',
// }
// },
data: {
message: 'message-data{} object !',
},
...
})
2. 在Vue 組件中data必須定義成函數形式, function定義方法和ES6定義均生效。
Vue.component('todo-item', {
data:function(){
return {mess: "aerchi--function"};
},
// data(){
// return {mess: "aerchi--data()"};
// },
template: '<li>{{mess}}</li>'
})
三、data三種寫法的區別:
1. 在簡單的vue實例應用中,三種寫法幾乎是沒有什麼區別的,因爲上述定義的 #app對象 不會被複用。
var app = new Vue({...})
2. 在組件應用的環境中,會存在多個地方調用同一個組件的情況,爲了不讓多個地方的組件共享同一個data對象,通過提供 data
函數,每次創建一個新實例後,我們能夠調用 data
函數,從而返回初始數據的一個全新副本數據對象。
請注意: 在一個組件的定義裏,data
必須聲明爲返回一個初始數據對象的函數。
這個與JavaScript的作用域特性有關,函數自己擁有私有的作用域,函數之間的作用域相互獨立,也就不會出現組件對數據的綁定出現交錯的情況。
export default{
data(){
return {
...
}
}
三、Vue官方中關於data的說明
(https://cn.vuejs.org/v2/api/?#data)
data
-
類型:
Object | Function
-
限制:組件的定義只接受
function
。 -
詳細:
Vue 實例的數據對象。Vue 將會遞歸將 data 的屬性轉換爲 getter/setter,從而讓 data 的屬性能夠響應數據變化。對象必須是純粹的對象 (含有零個或多個的 key/value 對):瀏覽器 API 創建的原生對象,原型上的屬性會被忽略。大概來說,data 應該只能是數據 - 不推薦觀察擁有狀態行爲的對象。
一旦觀察過,你就無法在根數據對象上添加響應式屬性。因此推薦在創建實例之前,就聲明所有的根級響應式屬性。
實例創建之後,可以通過
vm.$data
訪問原始數據對象。Vue 實例也代理了 data 對象上所有的屬性,因此訪問vm.a
等價於訪問vm.$data.a
。以
_
或$
開頭的屬性 不會 被 Vue 實例代理,因爲它們可能和 Vue 內置的屬性、API 方法衝突。你可以使用例如vm.$data._property
的方式訪問這些屬性。當一個組件被定義,
data
必須聲明爲返回一個初始數據對象的函數,因爲組件可能被用來創建多個實例。如果data
仍然是一個純粹的對象,則所有的實例將共享引用同一個數據對象!通過提供data
函數,每次創建一個新實例後,我們能夠調用data
函數,從而返回初始數據的一個全新副本數據對象。如果需要,可以通過將
vm.$data
傳入JSON.parse(JSON.stringify(...))
得到深拷貝的原始數據對象。 -
示例:
var data = { a: 1 } // 直接創建一個實例 var vm = new Vue({ data: data }) vm.a // => 1 vm.$data === data // => true // Vue.extend() 中 data 必須是函數 var Component = Vue.extend({ data: function () { return { a: 1 } } })
注意,如果你爲
data
屬性使用了箭頭函數,則this
不會指向這個組件的實例,不過你仍然可以將其實例作爲函數的第一個參數來訪問。data: vm => ({ a: vm.myProp })