使用情境

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

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

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 ) 的部分

範例程式碼:

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 那些沒告訴你的小細節

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