# Nghiên cứu về Reactivity trong Vue
======
---
## 1.Cơ chế Reactivity
---
#### 1.1. Reactivity system (hệ thống tương tác)
- Khi thay đổi data, model, thì view sẽ ngay lập tức cập nhật và thay đổi => two ways data binding
---
#### 1.2. Cơ chế
- Khi truyền vào một plain JavaScript object vào Vue instance => Vue sẽ duyệt qua toàn bộ property và định nghĩa thêm getter/setters cho mỗi property thông qua Object.defineProperty
---
Ví dụ:
```javascript=
{
id: 1,
name: 'My Item',
price: 9.99
}
```
- Sau khi Vue instance được khởi tạo, ta có thể xem object này trên console và thấy Vue define thêm getter và setter trên nó

---

note:
- 1 component instance ứng 1 watcher instance
- watcher: ghi lại thông tin của property được sử dụng và thay đổi trong suốt quá trình component render.
- Sau khi một setter được kích hoạt nó sẽ thông báo cho watcher kích hoạt một hành động re-render
---
### 2. Giải thích 1 số trường hợp không reactive với Object và Array
##### Object
```javascript=
var vm = new Vue({
data: {
a: 1
}
})// `vm.a` is now reactive
vm.b = 2 // `vm.b` is NOT reactive
```
##### Array
```javascript=
var vm = new Vue({
data: {
items: ['a', 'b', 'c']
}
})
vm.items[1] = 'x' // is NOT reactive
vm.items.length = 2 // is NOT reactive
```
---
2.1. Object
---
- Để property tự động reactive => khai báo trong data object => Vue kích hoạt getter/setter trong suốt quá trình khởi tạo instance.
- Để dữ liệu là reactive => khai báo dữ liệu với VueJS khi component được khởi tạo và lifecycle beforeMount được kích hoạt sau khi component được khởi tạo
---
2.1. Object
---
- add reactive property thông qua Vue.set(object, propertyName, value)
```javascript=
Vue.set(vm.someObject, 'b', 2)
```
- Hoặc dùng vue instance method vm.$set
```javascript=
this.$set(this.someObject, 'b', 2)
```
- Hoặc dùng Vue.util.defineReactive
```javascript=
// instead of `Object.assign(this.someObject, { a: 1, b: 2 })`
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })
```
note:
Gán nhiều giá trị thuộc tính vào một object đã có sẵn thông qua hàm Object.assign() hoặc _.extend(). Tuy nhiên những thuộc tính được add thêm vào object này cũng sẽ không được vue nhận ra thay đổi (hay là những nonactivity property). Trong trường hợp này hãy tạo ra một object mới với những thuộc tính muốn add thêm và trộn chúng với object đã tồn tại ở trên
---
## 2.2. Array
---
- Vue không phát hiện thay đổi với array trong trường hợp:
-- Khi set giá trị trực tiếp cho một item trong array với index của nó
vm.items[indexOfItem] = newValue
-- Khi thay đổi length của array
vm.items.length = newLength
---
## 2.2. Array
---
- Để giải quyết array reactivity => báo với reactivity system rằng trạng thái đã được thay đổi => hãy cập nhật
```javascript=
// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
```
Hoặc
```javascript=
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
```
{"metaMigratedAt":"2023-06-15T12:05:19.712Z","metaMigratedFrom":"Content","title":"Nghiên cứu về Reactivity trong Vue","breaks":true,"contributors":"[{\"id\":\"f57ffa19-0388-46c4-87bf-a523dba9f92f\",\"add\":6252,\"del\":3227}]"}