1. Vue的双向绑定原理
Vue的双向绑定是建立在MVVM的模型基础上的
数据层Model:应用的数据以及业务逻辑
视图层View: 应用的展示效果,各类的UI组件等
业务逻辑层ViewModel: 负责将数据和视图关联起来
双向绑定就是: 数据变化后更新视图,视图变化后更新数据。主要包含两部分:
* 监听器Observer: 对所有的数据属性进行监听
* 解析器Complier: 对每个元素节点的指令进行扫描和解析,根据指令替换数据,绑定对应的更新函数
具体的实现原理:
1. new Vue()执行初始化,对data通过Object.defineProperty进行响应化处理,这个过程发生在Observer中,每个key都会有一个dep实例来存储watcher实例数组
2. 对模板进行编译时,v-开头的关键词作为指令解析,找到动态绑定的数据,从data中获取数据并初始化视图,这个过程发生在Compiler里,如果遇到v-model,就监听input事件,更新data对应的值
3. 在解析指令的过程中,会定义一个更新函数和Watcher,之后对应的数据变化时Watcher会调用更新函数, new Watcher的过程中会去读取data的key,触发getter的依赖收集,将对应的watcher添加到dep里
4. 将来data中的数据一旦发生变化,会首先找到对应的dep,通知所有的watcher执行更新函数
手动实现一个响应式函数:
const data = {
a: 55,
b: {
cc: 66,
dd: {
rr: 66666666,
gg: {
hh: 66666,
},
},
},
};
const render = (key, val) => {
console.log(`set key = ${key}, val = ${val}`);
};
const reactive = (obj) => {
if (typeof obj !== "object") {
return;
}
for (const key in obj) {
defineReactive(obj, key, obj[key]);
}
};
defineReactive = (obj, key, val) => {
reactive(obj[key]);
Object.defineProperty(obj, key, {
get() {
return val;
},
set(newVal) {
if (val === newVal) {
return;
}
val = newVal;
render(key, val);
},
});
};
reactive(data);
data.a = 555;
data.b.cc = "cesshi";
data.b.dd.rr = 66666666;
data.b.dd.gg.hh = "6546456456";
console.log("data", JSON.stringify(data));
-------------------------------------------
set key = a, val = 555
set key = cc, val = cesshi
set key = hh, val = 6546456456
data {"a":555,"b":{"cc":"cesshi","dd":{"rr":66666666,"gg":{"hh":"6546456456"}}}}