浅析Vue双向数据绑定

浅析Vue双向数据绑定

双向数据绑定似乎是面试中常出现的问题,那么我们来了解下什么是双向数据绑定,他的原理又是什么。
首先,我们看下他的含义是怎么样定义的:数据的双向绑定,首先要对数据进行劫持监听,所以我们需要设置一个监听器Observer,用来监听所有属性。如果属性发生变化了,就需要告诉订阅者Watcher看是否需要更新。因为订阅者并非一个,所以需要有一个消息订阅器Dep来专门收集这些订阅者,然后在监听器Observer和订阅者Watcher之间进行统一管理的。还需要有一个指令解析器Compile,对每个节点元素进行扫描和解析,将相关指令对应初始化成一个订阅者Watcher,并替换模板数据或者绑定相应的函数,此时当订阅者Watcher接收到相应属性的变化,就会执行对应的更新函数,从而更新视图。
其次,我们看以下代码:

	<div id="app">
		{{message}}
	</div>
	//首先,我们需要引入我们的开发环境版本,他包含了有帮助的命令行警告
	<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	let data = {message:"test"}
	new Vue({
            el:"#app",
            //key名与value值相等时,可简写
            data
        })
     //控制台打印的data中的message是个响应式数据,当我们的message数据更改的时候,会自动更改
    console.log(data)

在这里我们需要解释一下,model层数据变化的时候,为什么vm就知道数据发生了变化,这就涉及到Vue的双向数据绑定原理,当Vue在创建vm的时候,会将数据配置到实例中,然后通过Object.defineProperty方法,为数据动态的添加getter与setter方法。
当获取数据的时候,会触发对应的getter方法,当设置数据时候则会触发对应的setter方法,当setter方法触发完成的时候,内部会进一步触发watcher,当数据改变了,视图则更新操作完成。
关于Vue双向数据绑定,其核心是 Object.defineProperty()方法,我们需要对Object.defineProperty()方法进行一个简要的介绍:
Object.defineProperty(obj, prop, descriptor) ,这个语法内有三个参数,分别为 obj (要定义其上属性的对象) prop (要定义或修改的属性) descriptor (具体的改变方法),通过下面的代码我们来大致的了解下:

	//定义一个空对象
	let obj = {}
	//这里设置一个中间变量
	let middle = 100
	Object.defineProperty(obj,"message",{
		get(){
			console.log('get方法执行了')
			return middle
		}
		set(val){
			console.log('set方法执行了',val)
			middle = val
		}
	}//获取对象属性的时候会执行get方法,会打印输出的内容,和返回的middle值
	console.log(obj.message) //get方法执行了,100
	//设置对象属性的时候会执行set方法,会打印输出内容
	obj.message = 200      //set方法执行了 200
	console.log(obj.message)  //get方法执行了,200

Object.defineProperty 是 ES5 中一个无法模拟的特性, 这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。
在数据变化的时候发布消息给订阅者(Watchr),触发响应的监听回调。
当然有利必然存在不足,Vue3这个版本的Object.defineProperty()方法存在以下缺点:
1、无法监听es6的Set、Map 变化;
2、无法监听Class类型的数据;
3、属性的新加或者删除也无法监听;
4、数组元素的增加和删除也无法监听。
针对Object.defineProperty的缺点,ES6 Proxy都能够完美得解决,它唯一的缺 点就是,对IE不友好,所以vue3在检测到如果是使用IE的情况下,会自动降级为Object.defineProperty的数据监听系统。
为了便于理解,制作了以下流程图:
流程图
最后,对上图进行一个简要的介绍:
监听器Observer,劫持并监听所有属性,有变动的,就通知订阅者。
订阅者Watcher,可以收到属性的变化通知并执行相应的函数,从而更新视图。
消息订阅器Dep来专门收集这些订阅者,然后在监听器Observer和订阅者Watcher之间进行统一管理的
解析器Compile,解析每个节点的相关指令,并根据初始化模板data数据以及初始化相应的订阅器。

发布了19 篇原创文章 · 获赞 2 · 访问量 545

猜你喜欢

转载自blog.csdn.net/qq_43756690/article/details/104949132