简单的理解vue中data数据的改变影响视图
前言
这个简化了vue虚拟dom的渲染,为了更好地理解vue中data数据的改变影响视图
这句话而写的。
请熟知 Object.defineProperty和原型原型链的知识,闭包也要有所掌握
我们用到的函数
data对象变量 | 我们需要的数据 |
---|---|
updateViews()方法 | 简化的渲染方法 |
observer()方法 | 判断元素并且运行绑定Object.defineProperty的方法 |
defineReactive()方法 | 绑定Object.defineProperty的具体操作 |
监听
渲染方法是固定的所以我们写在前面
updateViews方法
function updateViews () {
console.log('数据更新了');
}
普通监听
我们首先创建一个简单的data数据,同时调用observer()方法
const data = {
nihao: '123',
num: 2
}
observer(data)
写入observer的方法
function observer (data) {
for (const key in data) {
defineReactive(data, key, data[key])
}
}
写入defineReactive方法
function defineReactive (data, key, value) {
Object.defineProperty(data,key,{
get() {
return value
},
set(nwevalue) {
if (value !== nwevalue) {
updateViews()
value = nwevalue
}
}
})
}
请结合defineReactive和observer一起观看
- 首先我们创建了data数据并且同时调用observer(data)方法,将我们的创建的data传参传过去
- observer()方法接收到我们的data,然后进行for循环来为我们data每个元素绑定Object.defineProperty。
- 可以看到我们再Object.defineProperty里面的set方法中调用了, updateViews()渲染方法,这样才实现了,数据更新视图的要求。
但是现在有两个问题,如果data中的数据也是的对象,我们如何监听data对象中的对象中暑数据呢,说到了这里大家是不是想到了递归,没错我来进行代码演示
对象监听(深度监听)
data数据
const data = {
nihao: '123',
list: {
nihao: '15'
}
}
// 调用方法
observer(data)
observer的方法
function observer (data) {
if (typeof data !== 'object' || data ===null) {
return data;
}
for (const key in data) {
defineReactive(data, key, data[key])
}
}
defineReactive方法
function defineReactive (data, key, value) {
// 深度监听
observer(value)
Object.defineProperty(data,key,{
get() {
return value
},
set(nwevalue) {
if (value !== nwevalue) {
updateViews()
value = nwevalue
}
}
})
}
这里我们用到了递归
- 在observer加入了一个判断条件,如果我们传入的data他不是一个对象或者是空的,他就不用执行我们的递归了。因为根本没有必要。
- defineReactive方法中我们运用到了递归的知识。defineReactive的递归和observer的判断,打出了一套很好的配合。
又有新的问题,我们不能监听数组元素的增删改,所以这个也是Object.defineProperty的一个弊端
数组监听
时间太晚了现在凌晨2.30了,等我更新