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
接着处理 如果传入的值是数组...