Vue 双向绑定原理

关键词: 数据劫持、发布者-订阅者模式、Observe(监听器)、Dep(消息订阅器)、Watcher(订阅者)、Compile(解析器)、Object.defineProperty、Proxy、Reflect

vue的双向绑定原理就是通过数据劫持+发布者-订阅者模式实现的,可以借助下图参照

在这里插入图片描述
首先在初始化时,vue就会监听data,就是上图的Observe(监听器),监听所有属性;
如果属性发生变化就会通知Watcher(订阅者)
但是订阅者会有若干个,所以就引申出了 Dep(消息订阅器) 这个概念,用来收集所有的watcher,将所有watcher进行统一管理;
Compile(指令解析器) 对每一个节点元素进行扫描解析,将相关的指令(v-model, v-on…)初始化成一个 Watcher ,并替换模板数据或是相应的更新函数;
整体流程:

  1. 先创建一个Observe,劫持监听所有的属性,Dep 会收集所有watcher,当observe发现改动时就通知Dep,再由Dep通知Watcher;
  2. 每个watcher都绑定一个更新函数,watcher可以收到更新的内容,并执行相关更新函数;
  3. 实现一个解析器Compile,可以扫描和解析每个节点的相关指令,则Compile初始化这类节点的模板数据(使其显示在视图上),以及初始化相应的订阅者。

数据劫持

  1. vue2 - Object.defineProperty
    vue2的数据劫持是使用Object.defineProperty(obj, prop, descriptor)方法实现的,方法一共有三个参数, 分别是劫持的对象(obj),监听对象的某个属性就是对象的某个key(descriptor),改变方法(descriptor)
let student = { name: '张三' }
Object.defineProperty(student, 'name', {
	get: function () {
    	console.log('get')
         return 1
    },
    set: function (newValue) {
         console.log('set', newValue)
    }
})
student.name	// get
student.name = 2 // set 2
console.log('student.name', student.name) // get 1

上面是一个简单的例子,简单来对上文的数据劫持使用的defineProperty进行讲解
1) 当执行student.name语句的时候,就是一个get的操作,因此执行了我们定义的get方法,输出了get;
2)当我们想要给student的name赋值,此时就执行了定义的set方法;
3) 此时我们打印student.name 可以发现输出的不是定义student时的张三也不是重新赋值的1,这是因为我们在get方法里定写了 return 1, 因此无论进行什么操作都只能拿到1。

2 vue3 - Proxy

let student = {
	name: '张三',
    age: 12
}
const handle = {
	get: (target, prop) => {
   		console.log('get')
        return target[prop]
    },
    set: (target, prop, newValue) => {
    	console.log('set')
        target[prop] = newValue
    }
}
function reactive(target, handle) {
	return new Proxy(target, handle)
}
let student1 = reactive(student, handle)
console.log(student1) // 返回一个Proxy实例
student1.sex = 1	// set
student.name = '李四' // set
console.log(student1.name) // name: 李四 sex: 1

Proxy的相关内容在这里就不具体讲述了,通过上例,细心的读者应该可以发现,Object.defineProperty每次只能劫持对象的一个属性。而Proxy是直接劫持了整个对象。所以前者还需要对对象进行遍历,显然使用proxy的性能更好

数据劫持总结 通过上例,小编把数据劫持的这个模式,理解为劫持的 对象/对象属性 是 ‘艺人’, 使用数据劫持后相当于艺人找到了一个公关团队,所有外部想要看要 ‘艺人’ 的 形象(对象的值),都是会在‘公关团队’(自定义方法)下进行‘包装’(处理)后展示在大众面前。

以上仅是小编的个人理解,如有问题欢迎大家指出

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue双向绑定原理是通过数据劫持和发布订阅模式相结合的方式来实现的。在Vue中,当用户操作View时,ViewModel会感知到变化并通知Model进行相应的改变;反之,当Model发生改变时,ViewModel也能感知到变化并使View作出相应的更新。双向绑定的核心是使用了Object.defineProperty()方法来实现。 在Vue的初始化过程中,会对data数据进行劫持监听,这个过程由监听器Observe来完成。监听器会监听所有属性,当属性发生变化时,会通知订阅者Watcher来判断是否需要更新。由于订阅者Watcher可能有多个,所以需要一个消息订阅器Dep来统一管理这些订阅者。同时,还需要一个指令解析器Compile,用来扫描和解析每个节点的相关指令,将其初始化为一个订阅者Watcher,并替换模板数据绑定相应的函数。 当订阅者Watcher接收到属性的变化通知时,会执行对应的更新函数,从而更新视图。整个过程中,监听器Observer负责劫持并监听所有属性,订阅者Watcher负责接收属性的变化通知并执行相应的函数,消息订阅器Dep负责收集订阅者并通知Watcher触发更新,指令解析器Compile负责扫描和解析节点的指令并初始化相应的订阅者。 综上所述,Vue双向绑定原理是通过数据劫持+发布订阅模式相结合的方式来实现的,通过监听器、订阅者、消息订阅器和指令解析器等组件的协作,实现了数据和视图之间的双向绑定。 #### 引用[.reference_title] - *1* *2* [vue双向绑定原理](https://blog.csdn.net/qq_41645323/article/details/123324680)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Vue双向绑定原理](https://blog.csdn.net/weixin_52092151/article/details/119810514)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值