Vue 初心者筆記 #25 使用 vm.$set 動態添加新屬性

我們在使用 Vue 的時候,可能會碰到已經用 JavaScript 新增資料,畫面上卻沒有重新渲染出來的狀況,面對這種情況我們該如何解決呢?

使用情境

在使用 Vue 綁定資料的時候,如果一開始寫入資料的時候沒有預先定義某個資料的話,
該資料便不會跟著動態更新,並且會出現錯誤(不會出現 gettersetter),而這個資料也無法即時地反應在畫面上。

例如:使用 Click 觸發元件內的 addData 函式,新增一個原本沒有定義的資料 item

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var child = {
props: ['item'],
template: '#row-component',
data: function () {
return {
data: {},
};
},
methods: {
// 透過點擊觸發 addData 事件來新增資料
addData: function () {
this.$set(this.data, 'item', {
name: this.item.name,
});
console.log(this.data, this);
},
},
mounted: function () {
console.log('Component:', this);
},
};

透過 Console 可以看到 this.data 裡面其實是有這個 item 的,但是畫面上卻沒有呈現出來,
這是因為資料並未真正地進入 Vue 的資料結構內。

使用 vm.$set 動態添加新屬性

解決方法就是透過 vm.$set(target, key, value) 動態新增新的屬性。

參數說明:

  1. target:目標,通常是個 Object 或 Array
  2. key:我們要寫入的 key 的值
  3. value:我們要寫入的 value 的值

另外附上官方文件:API — Vue.js
可參考 Vue.set( target, propertyName/index, value ) 的部分

範例程式碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var child = {
props: ['item'],
template: '#row-component',
data: function () {
return {
data: {},
};
},
methods: {
addData: function () {
this.$set(this.data, 'item', {
name: this.item.name,
});
console.log(this.data, this);
},
},
mounted: function () {
console.log('Component:', this);
},
};

我們可以透過 Console 查看 data 內的 item,會發現這個時候 gettersetter 就會出現了。

總結

我們在使用 Vue 的時候,常常無法預先就把資料結構定義得很完整,
尤其是在搭配 AJAX 取得資料時,找回來的資料並沒有辦法預先定義,
這個時候就能使用 set 將資料寫入到 Vue 的結構裡面。

參考資料

  1. [那些關於 Vue 的小細節 ] 為什麼畫面沒有隨資料更新 - Vue 響應式原理(Reactivity) ~ PJCHENder 那些沒告訴你的小細節

以上資源是我自己整理過後的筆記,若有錯誤歡迎隨時和我聯繫。