【 vue数据响应原理深入学习】

vue数据响应原理深入学习

前言

作为一名长期搬砖人员来说、在一家创业行公司,在口罩的影响下,公司实在坚持不下去了,团队解散了!
继续新的开始。
接下来就复习复习,丰富自己。
由于长时间的作战在一线,一直围绕着,项目业务开展着每日的工作。也不知道当下企业面试重点在哪里啊,
实在不多少底气直接参加面试,所以还是花了有段时间复习了。
但是还是得在实战中终结经验最为重要;

1:vue 的响应原理你了解吗?能详细说一下它的具体实现原来吗?

作为一名前端开发工程是,应该避免不了的要去学习vue、在面试过程中只要你说你的技术栈是vue、那面试过程总会绕不过 “数据响应” 这个话题了;
那这个问题似乎还不是那么的好回答,回答太浅显,”你了解不够深入、技术一般“,回答:太深入,涉及面有太广、一下两下说不明白,现在还多了vue3, 那我回答的时候是回答vue2、还是回答 vue3、的呢;在这还说一下: 面试时如果项目中使用vue2,主要说说vue2的响应原理,如果vue2,vue3 在项目中都有使用过可以两者做对比回答,说出两种的差异点。

vue2 数据响应原理

说到vue2 的数据响应原理,这就先来说说:
Object.defineProperty
我们都知道 vue2 数据响应是居于 Object.defineProperty来实现的,但是它具体做了些什么呢?
Object.defineProperty(obj, prop, descriptor) 方法会直接在一个对象上定义一个 新属性,或修改一个 对象 的 现有属性,并返回此对象,其参数具体为:

  1. obj:要定义属性的对象
  2. prop:要定义或修改的 属性名称 或 Symbol
  3. descriptor:要定义或修改的 属性描述符
    接下来看一个简单的案例:
let testObj = {
    
    }
let name;
Object.defineProperty(testObj,'name',{
    
    
	get:()=>{
    
    
		console.log('get name:')
		return name
	},
	set: (newVal)=>{
    
    
		console.log('set name')
		name = newVal
	}
})
testObj.name = 'test name'
console.log(testObj.name)

通过这个简单实例;可以发现当我们使用Object.defineProperty 修饰 对象testObj 时,当我们去给testObj添加属性时会自动调用set 方法;当我们访问testObj 属性是会自动调用get 方法

原理分析
vue是使用MVVM模型架构设计的,这就必须满足于:数据与视图抱持同步;
所以vue需要做的就如果检测到数据的变化然后去更新视图;检查视图比较简单,无非就是使用事件监听。
结合着我们上面提到的Object.defineProperty 就能监听到数据属性变化了。即当触发set 方法时去通知我们跟新视图;

vue3 数据响应原理

实现原理
vue3 事件响应原理使用的是es6的新特性:Proxy
先来说说Proxy:

1、Proxy:是用来创建一个对象代理,从而实现对象的基本拦截和自定义(如:属性的查找、赋值、枚举、函数的调用、属性添加和删除等);
2、Proxy:可以对目标对象的读取,修改、函数的调用进行拦截操作、然后进行操作处理。不会直接操作对象,而是启动代理模式,通过对代理对象进行操作,这样的好处还能添加一下自定义额外的操作。

在MD 文档中我们可以看到对 Proxy 与 Reflect 结合使用的描述:

	const obj = new Proxy({
    
    },{
    
    
		get(target,propKey,receive){
    
    
			return Reflect.get(target,propKey,receive)
		},
		set(target,propKey,value,receive){
    
    
			return Reflect.set(target,propKey,value,receive)
		},
		deleteProperty(target,prop){
    
    
			return Reflect.deleteProperty(target, prop)
		}
	})

Proxy 的所有使用方式都是如上面的方式;接下来使用一个调用Proxy 的get 函数为例:

	const proxy = new Proxy({
    
    }, {
    
    
		get(target, prop){
    
    
			return 50
		}
	})
	proxy.name;// 50
	proxy.age;//50

上面的代码为一个构造函数,有两个参数,第一个为代理目标对象,第二个为配置对象,我们可以在第二个对象中定义我们需要对第一个目标对象进行代理的操作。

特别要注意:要想proxy 起作用,就必须对Proxy实例进行操作,而不是目标对象进行操作;

上面提到Proxy实例接收两个参数,第二个参数数定义要对目标函数进行拦截操作的对象,现在支持的拦截操作有13种
1、Reflect.apply()
2、Reflect.construct()
3、Reflect.defineProperty()
4、Reflect.deleteProperty()
5、Reflect.enumerate()
6、Reflect.get()
7、Reflect.getOwnPropertyDescriptor()
8、Reflect.getPrototypeOf()
9、Reflect.has()
10、Reflect.isExtensible()
11、Reflect.ownKeys()
12、Reflect.preventExtensions()
13、Reflect.set()
14、Reflect.setPrototypeOf()
这里就不去记一一将所有验证方法都记录了;

两者有什么不同

上面也说了 vue2 中双向数据绑定的原理采用 Object.defineProperty, vue3 中数据劫持原理使用Proxy代理;两种不同:

1、Object.definePropery 只能劫持对象的属性、不能监听数组、es6的新类型set map 这些数据类型进行监听,也不能监听到对应类型的,新增,删除等操作;
2、Peoxy 能够监听整个对象 而非属性,可以监听到数组的变化;

猜你喜欢

转载自blog.csdn.net/weixin_47659945/article/details/127918553