參考連接vue
templete:git
<div id="app"> <h2>{{dataObj.text}}</h2> </div>
js:github
new Vue({ el: '#app', data: { dataObj: {} }, ready: function () { var self = this; /** * 異步請求模擬 */ setTimeout(function () { self.dataObj = {};//真正實現數據更新的是這行代碼 self.dataObj['text'] = 'new text'; }, 3000); } })
上面的代碼很是簡單,咱們都知道vue中在data裏面聲明的數據才具備響應式的特性,因此咱們一開始在data中聲明瞭一個dataObj空對象,而後在異步請求中執行了兩行代碼,以下:web
self.dataObj = {}; self.dataObj['text'] = 'new text';
解決辦法: 首先清空原始數據,而後添加一個text屬性並賦值。而後數據和模版都更新裏。數組
vue的dom更新是異步的,即當setter操做發生後,指令並不會立馬更新,指令的更新操做會有一個延遲,當指令更新真正執行的時候,此時.text屬性已經賦值,因此指令更新模板時獲得的是新值。
具體流程以下:app
因此真正的觸發更新操做是self.dataObj = {};這一句引發的,因此單看上述例子,具備響應式特性的數據只有dataObj這一層,它的子屬性是不具有的。dom
Vue 包含一組觀察數組的變異方法,因此它們也將會觸發視圖更新。這些方法以下:異步
push() pop() shift() unshift() splice() sort() reverse()
因爲 JavaScript 的限制,Vue 不能檢測如下變更的數組:svg
當你利用索引直接設置一個項時,例如:vm.items[indexOfItem] = newValue
當你修改數組的長度時,例如:vm.items.length = newLength
舉個例子:this
var vm = new Vue({ data: { items: ['a', 'b', 'c'] } }) vm.items[1] = 'x' // 不是響應性的 vm.items.length = 2 // 不是響應性的
爲了解決第一類問題,如下兩種方式均可以實現和vm.items[indexOfItem] = newValue
相同的效果,同時也將觸發狀態更新:
// Vue.set Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice vm.items.splice(indexOfItem, 1, newValue)
你也可使用 vm.$set 實例方法,該方法是全局方法 Vue.set 的一個別名:
vm.$set(vm.items, indexOfItem, newValue)
爲了解決第二類問題,你可使用 splice:
vm.items.splice(newLength)
仍是因爲 JavaScript 的限制,Vue 不能檢測對象屬性的添加或刪除:
var vm = new Vue({ data: { a: 1 } }) // `vm.a` 如今是響應式的 vm.b = 2 // `vm.b` 不是響應式的
對於已經建立的實例,Vue 不能動態添加根級別的響應式屬性。可是,可使用 Vue.set(object, key, value)
方法向嵌套對象添加響應式屬性。例如,對於:
var vm = new Vue({ data: { userProfile: { name: 'Anika' } } })
你能夠添加一個新的 age 屬性到嵌套的 userProfile 對象:
Vue.set(vm.userProfile, 'age', 27)
你還可使用 vm.$set 實例方法,它只是全局 Vue.set 的別名:
vm.$set(vm.userProfile, 'age', 27)
有時你可能須要爲已有對象賦予多個新屬性,好比使用 Object.assign() 或 _.extend()。在這種狀況下,你應該用兩個對象的屬性建立一個新的對象。因此,若是你想添加新的響應式屬性,不要像這樣:
Object.assign(vm.userProfile, { age: 27, favoriteColor: 'Vue Green' })
你應該這樣作:
vm.userProfile = Object.assign({}, vm.userProfile, { age: 27, favoriteColor: 'Vue Green' })