DAY23 | 跟 Vue.js 認識的30天 - Vue 常用 API 說明(`$set`)

在談到如何使用 $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 為實例名)
vm.$set(object, propertyName, value)

//直接使用 this (this 指向實例本身)
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
// 必須確保屬性 people 已存在在 data 中
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); // [{…}, {…}, {…}, empty × 3]

但上述幾種方法用在 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 - 深入响应式原理