Vue 的响应式原理
1. 前言
-
当
data
中的数据发生改变,Vue内部是如何监听message数据的改变?使用
Object.defineProperty
-----> 监听对象属性的改变 -
当数据发生改变,Vue是如何知道要通知哪些人?哪些页面进行更新?
使用 发布订阅者模式 实现
2. 过程
2.1 首先new Vue()
new Vue({
el: "#app",
data: {
name: "fct",
age: 18
}
})
2.2 针对data
中的数据
利用Object.defineProperty
对data对象中的数据进行重构,设置get
、set
。用以监听数据的改变。
new Observer(data); // 处理data
// 观察者
class Observer {
constructor(data) { // data 即为 Vue中data对象数据
this.data = data;
Object.keys(data).forEach(item => {
this.defineReactive(this.data, key, data[key])
})
}
defineReactive(obj, key, val) {
// 一个属性 key ,对应一个 Dep 对象
const dep = new Dep();
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
set(newValue) {
if (newValue === value) {
return;
}
value = newValue;
// 通知订阅者对象watcher,进行视图更新
dep.notify();
},
get() {
// 添加到订阅者队列
if (Dep.target) {
// target 即为watcher
dep.addSub(Dep.target);
}
return value;
}
})
}
}
-
每个data中的属性都对应一个Dep对象(
dependence
依赖),其中有属性:subs
(订阅者subscriber
),该属性对应的值是数组,数组中每一项为watcher
对象(观察者)。class Dep { constructor() { this.subs = [] // 存放watcher对象数组 } notify() { // 通知subs对象中所有watcher,进行更新 // watcher 对象都有update方法进行视图更新 this.subs.forEach(sub => { sub.update(); }) } addSub(sub) { // 添加 watcher对象 this.subs.push(sub); } }
2.3 针对 el
模板
解析模板中何处使用了data
中的数据,为每一处使用创建一个watcher
对象。并将对象推入到相应data
数据的Dep
对象的subs
数组中。
new Compiler('el', this); //处理el('#app')
class Compiler { //编译
constructor() {
// ....
new Watcher(); //编译时找到{{}}使用了data中的属性,新建watcher对象
}
}
class Watcher {
constructor() {
Dep.target = this; //1. 设置target,getter中if满足条件
this.update(); //2. 进订阅者数组
Dep.target = null; //3. 赋空
}
update() {
// 更新视图, this.node.nodeValue设置值
this.node.nodeValue = this.vm[this.name]; // this.vm即为Vue实例
// this.vm[this.name]取属性值,会调用data对象属性的getter,然后添加进sub数组
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器