在談到如何使用 $set
前,就必須先了解一下 Vue 是如何實現數據響應的,所以另外寫了一篇有關於 Vue 響應式原理 - Vue.js 源碼分析 - Vue 物件(Object)響應式原理的文章,簡單記錄一下自己的理解過程。
Vue 資料的響應式是在 Vue Init 階段就將 data
變成響應式了(執行 observe()
),所以資料如果一開始沒有在 data
裡面的話,就不會是響應式的。
讓資料變成響應式
1 2 3 4 5 6 7 8 9
| Vue.set(object, propertyName, value)
vm.$set(object, propertyName, value)
this.$set(object, propertyName, value)
|
物件
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const vm = new Vue({ data: { people:{ mark:{ gender: 'male', age: 19, }, } } })
vm.people.mary = {gender: 'female', age: 20}
vm.$set(vm.people, 'john', {gender: 'male', age: 50})
|
同時加入多個新屬性
1 2
| vm.people = Object.assign({}, vm.people, {michelle}:{gender: 'female', age: 20},bill:{gender: 'male', age: 50}})
|
MDN - Object.assign()
陣列
在使用 Vanilla JS 操作陣列時,我們常會用以下幾種方法來改變陣列中某一項的值,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13
| let arr = [ { name: "mary", gender: "female", age: 20 }, { name: "john", gender: "male", age: 50 }, 3 ];
arr[2] = { name: "Celeste", gender: "female", age: 18 }; console.log(arr);
arr.length = 5; console.log(arr);
|
但上述幾種方法用在 Vue 中來改變陣列的值,將會將該值變成非響應式的。
1 2 3 4 5 6 7 8 9 10 11 12 13
| const vm = new Vue({ el: "#vm", data: { arr: [ { name: "mary", gender: "female", age: 20 }, { name: "john", gender: "male", age: 50 }, 3 ] } });
vm.arr[2] = { name: "Celeste", gender: "female", age: 18 };
|
如果要想要改變陣列的值同時還要維持響應式的話,就必須使用 Vue 特別規定的幾種方法。
1 2 3
| vm.$set(vm.arr, 0, { name: "Michelle", gender: "female", age: 18 });
vm.arr.splice(1, 1, { name: "Celeste", gender: "female", age: 18 });
|
其他方法可以參考 Vue.js - 数组更新检测
Demo
See the Pen
DAY23 | 跟 Vue.js 認識的30天 - Vue 常用 API 說明(`$set`) by Celeste6666 (@celeste6666)
on CodePen.
參考資料
Vue.js - 深入响应式原理