力有不逮的對象
眾所周知,在 Vue 中,直接修改對象屬性的值無法觸發(fā)響應(yīng)式。當(dāng)你直接修改了對象屬性的值,你會發(fā)現(xiàn),只有數(shù)據(jù)改了,但是頁面內(nèi)容并沒有改變。
這是什么原因?
原因在于: Vue 的響應(yīng)式系統(tǒng)是基于Object.defineProperty這個方法的,該方法可以監(jiān)聽對象中某個元素的獲取或修改,經(jīng)過了該方法處理的數(shù)據(jù),我們稱其為響應(yīng)式數(shù)據(jù)。但是,該方法有一個很大的缺點(diǎn),新增屬性或者刪除屬性不會觸發(fā)監(jiān)聽,舉個栗子:
var vm = new Vue({ data () { return { obj: { a: 1 } } }})// `vm.obj.a` 現(xiàn)在是響應(yīng)式的vm.obj.b = 2// `vm.obj.b` 不是響應(yīng)式的原因在于,在 Vue 初始化的時候, Vue 內(nèi)部會對 data 方法的返回值進(jìn)行深度響應(yīng)式處理,使其變?yōu)轫憫?yīng)式數(shù)據(jù),所以, vm.obj.a 是響應(yīng)式的。但是,之后設(shè)置的 vm.obj.b 并沒有經(jīng)過 Vue 初始化時響應(yīng)式的洗禮,所以,理所應(yīng)當(dāng)?shù)牟皇琼憫?yīng)式。
那么,vm.obj.b可以變成響應(yīng)式嗎?當(dāng)然可以,通過 vm.$set 方法就可以完美地實(shí)現(xiàn)要求,在此不再贅述相關(guān)原理了,之后應(yīng)該會寫一篇文章講述 vm.$set 背后的原理。
更凄慘的數(shù)組
上面說了這么多,還沒有提到本篇文章的主角——數(shù)組,現(xiàn)在該主角出場了。
比起對象,數(shù)組的境遇更加凄慘一些,看看官方文檔:
由于 JavaScript 的限制, Vue 不能檢測以下變動的數(shù)組:
vm.items[indexOfItem] = newValue 當(dāng)你修改數(shù)組的長度時,例如:vm.items.length = newLength有可能官方文檔不是很清晰,那我們繼續(xù)舉個栗子:
var vm = new Vue({ data () { return { items: ['a', 'b', 'c'] } }})vm.items[1] = 'x' // 不是響應(yīng)性的vm.items.length = 2 // 不是響應(yīng)性的也就是說,數(shù)組連自身元素的修改也無法監(jiān)聽,原因在于, Vue 對 data 方法返回的對象中的元素進(jìn)行響應(yīng)式處理時,如果元素是數(shù)組時,僅僅對數(shù)組本身進(jìn)行響應(yīng)式化,而不對數(shù)組內(nèi)部元素進(jìn)行響應(yīng)式化。
這也就導(dǎo)致如官方文檔所寫的后果,無法直接修改數(shù)組內(nèi)部元素來觸發(fā)響應(yīng)式。
那么,有沒有破解方法呢?
當(dāng)然有,官方規(guī)定了 7 個數(shù)組方法,通過這 7 個數(shù)組方法,可以很開心地觸發(fā)數(shù)組的響應(yīng)式,這 7 個數(shù)組方法分別是:
push() pop() shift() unshift() splice() sort() reverse()可以發(fā)現(xiàn),這 7 個數(shù)組方法貌似就是原生的那些數(shù)組方法,為什么這 7 個數(shù)組方法可以觸發(fā)應(yīng)式,觸發(fā)視圖更新呢?
新聞熱點(diǎn)
疑難解答
圖片精選