vue3.0梳理之响应式数据原理

vue2.0的defineProperty

  • 2.0响应式原理在使用中其实理解与否区别不大,但是使用肯定是不但要知其然,也要知其所以然的,简单概述一下2.0的数据响应式原理

1.vue2.0通过Object.defineProperty来劫持对象属性的getter和setter操作(以我的理解大致可以作为说绑定了一个事件,监听事件就是get和set,当数据被改变时,就会触发)

  • defineProperty内的参数有以下属性
释义
obj要定义属性的对象。
prop要定义或修改的属性的名称或 Symbol 。
descriptor要定义或修改的属性描述符。
  • descriptor内的参数也较为简单
属性描述默认值
configurable描述符能否被改变false
enumerable能否被枚举false
value该属性对应的值。undefined。
writable能否被改写false
get当访问该属性时调用undefined
set当属性值被修改时调用。该方法接受一个被赋予的新值undefined
  • observe的极简实现如下
     var obj = {};
     Object.defineProperty(obj, 'key1', {
     //key1在这里实际上就是循环绑定时传入的prop
         get: function () {
             return val;
         },
         set: function (newVal) {
             val = newVal;
             //一般我们用到的也就是此处的set,这个set被触发的时候,就可以在此处进行逻辑
             //vue2.0在逻辑中进行了runder函数的触发
         }
     });
     document.addEventListener('keyup', function (e) {
         obj.key1= e.target.value;
     });

在上述observe函数的实现里,其实还有一个很重要的,就是需要遍历要绑定的数据,递归,拆分成非对象类型的基础类型来添加劫持

vue3.0的Proxy

Proxy的劫持与2.0使用上实际上区别不大,但是有所优化及进步

描述
target要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
handler一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p 的行为。
  • 3.0内的更加简单明了,但是总结在handler内的代理操作更加的完善,很多,十三个拦截方式,想要知道的可以去搜一下Proxy的handler内的能力都有哪些,在我们自己用到及需要了解的其实还是getter和setter操作,升级版的get和set
     var obj = {};
     var obj1 = new Proxy(obj, {
         get: function (target, key, receive) {
             return target[key];
         },
         set: function (target, key, newVal, receive) {
             target[key] = newVal;
         }
     })
     document.addEventListener('keyup', function (e) {
         obj1[0] = e.target.value;
     });

3.0的极简代码与2.0看似没啥区别,但是实际上省略了比较多的步骤,省略了遍历,递归的等步骤,直接劫持对象,Proxy返回一个新对象,可以只操作新对象达到目的,而Object.defineProperty只能遍历对象属性直接修改

修改对象内属性等离谱的操作也变得可以触发set,再也不用深拷贝之类的操作来达到触发更新的目的

  • 结尾放一下暴漏弊端的2.0的defineProperty使用代码,助于理解
	observe.prototype.observe = function(obj){
		var val;
		var that = this;
		for(let key in obj){//遍历所有属性,依次设置监听
			val = obj[key];
			if(typeof val ==='object'){
				this.observe(val)	//如果是对象的话进行递归
			}else{
				Object.defineProperty(this.$data,key,{
					get:function(){
						return val;
					},
					set:function(newVal){
						val = newVal;
						that.render();
					}
				})
			}
		}
	}
	vue.prototype.render = function(){}//完成渲染的方法

3.0也对vdom的对比进行了升级; 2.0的diff算法会将所有的dom节点依次展开,但是3.0的diff算法会将无需更新数据的节点省略,不会展开和对比节点,这点对性能来说是比较大的优化

关于优化点的动态节点与静态节点的标记有较为成熟的分析可以搜索一下嗷

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值