Vue數據綁定失效
首先,我們得明白Vue數據響應的原理:
以對象為例:當把一個JavaScript對象傳給Vue實例的data選項時,Vue將遍歷此對象所有的屬性,並使用Object.defineProperty把這些屬性全部轉為getter/setter,
而getter/setter可以做到追蹤依賴,在屬性被訪問和修改時通知變化。
那麽,什麽是getter/setter ?
var person = {
defaultname: ‘tom‘,
get name() {
return this.defaultname
},
set name(val) {
this.defaultname = val
console.log("觸發了set")
}
}
person.name =>"tom"
person.name = 123 =>觸發了set
person.name =>123
getter/setter其實就是get、set方法,set能檢測到數據的改變並進行操作。
但在有些情況下setter不能檢測到數據的變化,即沒有觸發set。
例如:
person.name = {name: ‘tom‘} =>觸發了set person.name =>{name: "tom"} person.name.name= 123123 =>沒有打印出任何信息,說明修改name的屬性值並沒有觸發set方法。 person.name.sex = 333 =>沒有打印出任何信息,說明添加name的屬性值並沒有觸發set方法。 delete person.name.name =>沒有打印出任何信息,說明刪除name的屬性值並沒有觸發set方法。 Object.defineProperty(person.name, ‘name‘, {value: 4444}) =>沒有打印出任何信息,說明Object.defineProperty也沒有觸發set方法。
追蹤依賴在這種情況下並沒有形成,這時數據綁定失效的根本原因。
失效場景總結:
對象
修改、添加、刪除對象的屬性值
數組
設值,修改長度,push、pop、shift、unshift等原生方法
------------------------------------------------------------------------
解決方案
對象
單個屬性:可使用Vue.set(object, key, value)方法將響應屬性添加到嵌套的對象上
多個屬性:替換方法,即:創建一個新的對象賦值給原對象
如:this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })
數組
Vue提供的對原生方法修改的變異方法:
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
非變異方法(替換方法):(本質上也是創建一個新的數組賦值給原數組)
如:
example1.items = example1.items.filter(function (item) {
return item.message.match(/Foo/)
})
那麽這兒就有一個思考,替換方法是否低效?是否會導致dom樹的重新渲染?
不用擔心,大膽用!因為Vue為了使得 DOM 元素得到最大範圍的重用而實現了一些智能的、啟發式的方法,所以用一個含有相同元素的數組去替換原來的數組是非常高效的操作。
-----------------------------------------------------------------------------------------
另外,還有一種失效的場景,即給data對象添加屬性時失效,這裏得聲明:
初始化時才會對屬性執行getter/setter轉化過程,所以屬性必須在data對象上存在,或者設置為某個對象的屬性。
Vue數據綁定失效