Vue中數(shù)組與對象修改觸發(fā)頁面更新的機制與原理解析
Vue中關(guān)于數(shù)組與對象修改觸發(fā)頁面更新的機制與原理簡析
相關(guān)問題
數(shù)組
使用索引直接賦值與直接修改數(shù)組length時,不會觸發(fā)頁面更新。
例如:
<script>
export default {
name: "HomeView",
data: () => ({
list1: ["A", "B"],
}),
methods: {
btnClicked() {
this.list1[0] = "C"
this.list1[2] = "C"
},
},
}
</script>或是
<script>
export default {
name: "HomeView",
data: () => ({
list1: [{ text: "123" }, { text: "456" }],
}),
methods: {
btnClicked() {
this.list1[0] = { text: "789" }
},
},
}
</script>
頁面并不會觸發(fā)更新。
對象
頁面初始化完成后,在方法中直接對data內(nèi)聲明對象當(dāng)前不存在的屬性進行賦值來為對象新增屬性時,頁面也不會響應(yīng)渲染。
例如:
<script>
export default {
name: "HomeView",
data: () => ({
obj1: { a: "a", b: "b" },
}),
methods: {
btnClicked() {
this.obj1.c = "c"
},
},
}
</script>
頁面并不會觸發(fā)更新。
原因
Vue在初始化時會將data內(nèi)所有的屬性嵌套遍歷并重寫其Getter和Setter方法,借此實現(xiàn)響應(yīng)式屬性。
然而對于在頁面渲染完成后加入data的屬性,Vue并不會將其變?yōu)轫憫?yīng)式。
一些深入的探究
數(shù)組
Vue對于數(shù)組是僅將其對應(yīng)下標的對象的屬性變?yōu)轫憫?yīng)式,而這個下標本身是無法成為響應(yīng)式的。
data: () => ({
list1: [{ text: "123" }, { text: "456" }],
})使用如上的data聲明。
方法A:
this.list1[0] = { text: "789" }方法B:
this.list1[0].text = "789"
方法B可以被正確響應(yīng)而方法A不可以。
方法A將數(shù)組下標為0的位置替換為了一個新的對象,而因為數(shù)組下標不是響應(yīng)式的,因此沒有觸發(fā)頁面刷新。
同時,由于數(shù)組下標為0的位置替換為了一個新的對象,而這個新的對象并沒有被配置為響應(yīng)式,那對于這個對象屬性的修改也不會觸發(fā)頁面更新。如下:
this.list1[0] = { text: "789" }
this.list1[0].text = "456"
由于新的對象的屬性并沒有被配置為響應(yīng)式,那么即使對這個對象的屬性進行修改,頁面也不會被更新。
既然下標本身無法成為響應(yīng)式,不妨嘗試:
<script>
export default {
name: "HomeView",
data: () => ({
list1: ["A", "B"],
}),
methods: {
btnClicked() {
this.list1[0] = "C"
},
},
}
</script>
通過下標修改數(shù)組的對應(yīng)值也無法觸發(fā)視圖更新。
對象
data: () => ({
obj1: { a: { text: "a" }, b: { text: "b" } },
}),
使用如上的data聲明。
this.obj1.a = { text: "c" }成功觸發(fā)視圖更新。
與數(shù)組下標不同,對象的屬性在初始化是被定義為響應(yīng)式的,因此直接對屬性賦值對象是能夠觸發(fā)視圖更新的。不像對數(shù)組的對應(yīng)下標賦值而不會觸發(fā)視圖更新。
解決方案
數(shù)組
1. 內(nèi)置API
如果需要向數(shù)組加入新的成員,則可以直接使用數(shù)組的push方法。
此外,下列數(shù)組方法也可以自動的觸發(fā)視圖刷新:
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
2. 將數(shù)組重新賦值,修改引用地址
為數(shù)組新增一個字符串成員"C"
this.list1 = this.list1.concat(["C"])
由于list1是data的屬性,list1的引用發(fā)生改變,就會觸發(fā)視圖更新。
修改數(shù)組的第一個值
let tempList = this.list1.concat([]) // 深拷貝,等價于一個新數(shù)組,使用slice,JSON都可以。 tempList[0] = "666" this.list1 = tempList
通過原數(shù)組新建一個新數(shù)組,修改新數(shù)組后再將新數(shù)組賦值給原數(shù)組,由于原數(shù)組作為data的屬性,其引用被修改,觸發(fā)視圖更新。
3. Vue.$set() 方法
使用Vue.$set可以為data對象添加一個新的響應(yīng)式屬性,且觸發(fā)視圖更新。
定義:
Vue.$set(對象或數(shù)組, 對象屬性名或數(shù)組下標, 值)
向list1對象的0索引位置賦值一個新的響應(yīng)式對象,同時觸發(fā)視圖更新:
Vue.$set(this.list1, 0, { text: "789" })如果在組件中應(yīng)使用this.$set來代替:
this.$set(this.list1, 0, { text: "789" })對象
1. 將對象重新賦值,修改引用地址
思路與數(shù)組的類同。
使用JSON、手寫遞歸、lodash深拷貝均可,但如果對象內(nèi)含方法,則不能使用JSON來完成深拷貝。
深拷貝完成后修改對應(yīng)屬性后賦值給原對象即可。
2. Vue.$set() 方法
對象同樣可以使用$set() 方法修改。
定義:
Vue.$set(對象或數(shù)組, 對象屬性名或數(shù)組下標, 值)
將obj1對象的a屬性賦值為字符串"b"并觸發(fā)視圖更新:
Vue.$set(this.obj1, a, "b")
如果在組件內(nèi),則應(yīng)使用:
this.$set(this.obj1, a, "b")
到此這篇關(guān)于Vue中關(guān)于數(shù)組與對象修改觸發(fā)頁面更新的機制與原理簡析的文章就介紹到這了,更多相關(guān)Vue數(shù)組與對象修改觸發(fā)頁面更新內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
實現(xiàn)shallowReadonly和isProxy功能示例詳解
這篇文章主要為大家介紹了實現(xiàn)shallowReadonly和isProxy功能示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-12-12
Vue.js基礎(chǔ)之監(jiān)聽子組件事件v-on及綁定數(shù)據(jù)v-model學(xué)習(xí)
這篇文章主要為大家介紹了Vue.js基礎(chǔ)之監(jiān)聽子組件事件v-on及綁定數(shù)據(jù)v-model學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-06-06
vue.js中關(guān)于點擊事件方法的使用(click)
這篇文章主要介紹了vue.js中關(guān)于點擊事件方法的使用(click),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-08-08
vue執(zhí)行配置選項npm?run?serve的本質(zhì)圖文詳解
本地開發(fā)一般通過執(zhí)行npm run serve命令來啟動項目,那這行命令到底存在什么魔法?下面這篇文章主要給大家介紹了關(guān)于vue執(zhí)行配置選項npm?run?serve的本質(zhì)的相關(guān)資料,需要的朋友可以參考下2023-05-05
vue+vuex+json-seiver實現(xiàn)數(shù)據(jù)展示+分頁功能
這篇文章主要介紹了vue+vuex+json-seiver實現(xiàn)數(shù)據(jù)展示+分頁功能,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2019-04-04

