其实是牛哥
const data = {
"name":"mimi",
"age":"18"
} //数据源
const obs = new Observer(data);
function Observer(data) {
const keys = Object.keys(data);//把所有data的键值按顺序放入一个数组keys中
keys.forEach((key)=>{
Object.defineProperty(this,key,{
//因为获取和修改data的值时,都是调用了obs的属性对应的get和set,
//而不是data属性的get和set,因此不会死循环栈溢出
get() {
return data[key];
},
set(val) {
data[key] = val;
cosole.log("数据改变,开始重新渲染模板");//发布者发布消息给订阅者,告诉订阅者数据改变了,快点改模板
}
})
})
}
let vm = {}
vm._data = data = obs;//实现mini版data const data = {
"name":"mimi",
"age":18
}
Object.defineProperty(data,"name",{
get() {
return data["name"];
/**第一次触发get返回时,
需要读取data中的name属性,再次触发第二次get函数,同理,不断触发get函数*/
},
set(val) {
/**第一次触发set时,需要修改data中的
name属性,再次触发第二次set函数,同理,不断触发set函数*/
data["name"] = val;
console.log("数据改变,渲染模板")
}
}) 采用数据劫持和发布者-订阅者模式的组合,Vue实现了双向数据绑定的功能。数据劫持确保了属性的变化能够被追踪和监听,而发布者-订阅者模式则负责数据变化时的通知和更新操作。