实现一个简单版本的vue检测数据改变的代码
let data = {
name: 'sakamoto',
address: 'tokyo'
}
const obs = new Observer(data)
console.log(obs)
let vm = {}
vm._data = data = obs
function Observer(obj) {
const keys = Object.keys(obj)
keys.forEach(key => {
Object.defineProperty(this, key, {
get() {
console.log('get')
return obj[key]
},
set(newVal) {
console.log('set a new number, 解析新模板')
obj[key] = newVal
}
})
})
}
当数据变化时,如何被动获取检测数据的变化。 实现一个 Observer 函数,可以看到该函数内获取到数据之后,然后获取数据的所有key值 然后使用 defineProperty 来创建 Observer 的实例对象,此时对于 data 上的每一个值都会在 obs 重新创建,并且形成 get 以及 set 函数。
可以在控制台观察到
此时我们模仿 vm 的形式,创建一个 vm 对象,然后对 data 以及 vm 上的_data 赋值 obs,就可以得到类似于 vm 的对象结构。
此时我们改变 data 中的某一属性值时,就可以观察到 set 函数被调用。
但是这个简单版本的数据监听,仅限于这种简单的数据结构,如果 data 里再含有对象或者数据,那么就监听不到了。
let data = {
name: 'sakamoto',
address: 'tokyo',
obj: {
a: '1',
b: '2'
}
}
可以观察到 obj 里面的对象并没有形成 set 和 get ,原因很简单,我们 observer 函数代码仅仅进行了比较简单的遍历,并没有深层次的去为内在的对象 obj 来创建 set 以及 get 。