Vue2動態(tài)添加屬性導(dǎo)致頁面不更新的原因與解決方案
一、問題示例
我們先來看一個簡單的例子:
<div id="app">
<p v-for="(value, key) in item" :key="key">
{{ value }}
</p>
<button @click="addProperty">動態(tài)添加新屬性</button>
</div>
Vue 實例代碼如下:
const app = new Vue({
el: "#app",
data: () => ({
item: {
oldProperty: "舊屬性"
}
}),
methods: {
addProperty() {
this.item.newProperty = "新屬性"; // 動態(tài)添加新屬性
console.log(this.item); // 數(shù)據(jù)確實更新了
}
}
});
點擊按鈕后,console 能打印出帶有 newProperty 的對象,但頁面上并沒有新增一行。
二、原理分析
為什么會出現(xiàn)這種情況?
Vue2 的響應(yīng)式系統(tǒng)是基于 Object.defineProperty 實現(xiàn)的。
const obj = {};
let val = "初始值";
Object.defineProperty(obj, "foo", {
get() {
console.log(`get foo: ${val}`);
return val;
},
set(newVal) {
if (newVal !== val) {
console.log(`set foo: ${newVal}`);
val = newVal;
}
}
});
當訪問或修改 foo 時,會觸發(fā) getter/setter。但如果直接新增屬性:
obj.bar = "新屬性";
此時 bar 并沒有通過 Object.defineProperty 設(shè)置攔截,因此不是響應(yīng)式屬性。
這正是 Vue2 無法檢測到新屬性的原因。
三、解決方案
Vue2 不允許在已創(chuàng)建的實例上直接新增響應(yīng)式屬性,但我們有幾種方式來解決:
1. 使用 Vue.set()
Vue.set(this.item, "newProperty", "新屬性");
這樣 Vue 會調(diào)用內(nèi)部的 defineReactive,為新屬性建立響應(yīng)式綁定,并觸發(fā)視圖更新。
簡化源碼邏輯如下:
function set(target, key, val) {
defineReactive(target, key, val);
dep.notify(); // 通知視圖更新
return val;
}
2. 使用 Object.assign()
直接使用 Object.assign() 并不能觸發(fā)更新,但如果創(chuàng)建一個新對象賦值給原對象,就可以:
this.item = Object.assign({}, this.item, { newProperty: "新屬性" });
這種方式適合一次性添加多個屬性。
3. 使用 $forceUpdate()
強制讓 Vue 實例重新渲染:
this.item.newProperty = "新屬性"; this.$forceUpdate();
不過,這種方式不推薦,因為大多數(shù)情況下說明代碼結(jié)構(gòu)存在問題。
四、小結(jié)
- 少量新增屬性 → 使用
Vue.set()。 - 大量新增屬性 → 使用
Object.assign()創(chuàng)建新對象。 - 臨時解決方案 → 使用
$forceUpdate()強制刷新(不建議)。
需要注意的是:Vue3 使用 Proxy 實現(xiàn)響應(yīng)式,可以直接動態(tài)添加屬性,依然能觸發(fā)更新,不再存在這個問題。
到此這篇關(guān)于Vue2動態(tài)添加屬性導(dǎo)致頁面不更新的原因與解決方案的文章就介紹到這了,更多相關(guān)Vue2動態(tài)添加屬性頁面不更新內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue?3.0使用element-plus按需導(dǎo)入方法以及報錯解決
Vue3是不能直接使用Element-ui了,需要換成Element-plus,下面這篇文章主要給大家介紹了關(guān)于vue?3.0使用element-plus按需導(dǎo)入方法以及報錯解決的相關(guān)資料,需要的朋友可以參考下2024-02-02
Vue中watch監(jiān)聽屬性新舊值相同的問題解決方案
這篇文章主要給大家分享了Vue中watch監(jiān)聽屬性新舊值相同問題解決方案,如果有遇到相同問題的朋友,可以參考閱讀本文2023-08-08

