Vue響應式特點
1.使用對象時, 必須先聲明, 這個屬性纔是響應式的
2. 給對象數據遞歸增加 getter和setter
3. 數組裏套對象, 對象時支持響應式變化的,常量則沒有效果
4. 修改數組的索引及長度, 是不會導致視圖更新
5. 如果是新增的數據(對象類型), vue 纔會幫你監控
vue 要監聽的數據 可能是對象, 數組, 或者 其它基本值
1. 首先 說基本數據
// 創建一個觀察者函數
function observer(obj) {
// 判斷obj如果不是對象 或者 是 null, 就直接返回
if (typeof obj !== "object" || typeof obj == null) {
return obj
}
// 判斷數據是不是數組
if (Array.isArray(obj)) {
} else {
// 否則 就是對象
for (let key in obj) {
// 該函數只處理數據是對象的情況
defineReactive(obj, key, obj[key])
}
}
}
function defineReactive(obj, key, value) {
}
// 測試
let data = 10
console.log(observer(data)) // 10
第一步完事, 接着處理判斷是對象的情況 , 也就是 defineReactive 函數
function defineReactive(obj, key, value) {
Object.defineProperty(obj, key, {
get() {
return value
},
set(newValue) {
if (value !== newValue) {
value = newValue
console.log("數據更新:" + newValue)
}
}
})
}
let data = {
age: 10
}
observer(data)
data.age = 30 // 數據更新:30
接着看這個函數, 現在只是修改 data.age = 30 ,這一層值, 如果是多層對象嵌套, 會發現不會再更新了 ,比如下邊這樣的
let data = {
age: {
id: 10
}
}
observer(data)
data.age.id = 20
上邊的函數,只是處理了第一層數據,會加上 getter, setter,但是多層嵌套後, 並沒有增加響應式
let data = {
name: "李四",
age: {
id: 10
}
}
observer(data)
data.age.id = 20
data.name = "王參謀"
console.log(data)
但是隻更新一次,所以就需要遞歸處理數據, 也就是說, 新修改的數據 可能是個對象, 第一層遍歷後, 它的值也可能是個對象,
所以需要在兩個地方都遞歸調用 observer( ) 函數
遞歸後
function defineReactive(obj, key, value) {
observer(value) // 遞歸處理函數
Object.defineProperty(obj, key, {
get() {
return value
},
set(newValue) {
if (value !== newValue) {
value = newValue
observer(value) // 遞歸函數
console.log("數據更新:" + newValue)
}
}
})
}
let data = {
name: "李四",
age: {
id: 10
}
}
observer(data)
data.age.id = 20
data.name = "王參謀"
console.log(data);
console.log(data.age);
可以看到,遞歸後, 給所有的對象都添加了setter 和 getter
接着處理 如果傳入的值是數組...