Vue面试考点之Vue3

Vue2数据双向绑定是通过采用数据劫持结合发布者-订阅者模式的方式来实现的。通过Object.defineProperty()来劫持各个属性的setter,getter。修改触发set方法赋值,获取触发get方法取值,在数据变动时发布消息给订阅者,触发相应的回调并通过数据劫持发布信息。

但是 Object.defineProperty() 只能对属性进行数据劫持,不能对整个对象进行劫持,同理无法对数组进行劫持。Vue 框架是通过遍历数组和递归遍历对象,从而达到利用 Object.defineProperty() 也能对对象和数组(部分方法的操作)进行监听

Vue的数组响应式是如何实现的?它是以Array.prototype为原型,创建了一个arrayMethods对象,使用Object.setPrototypeOf()强制让数组指向arrayMethods,这样就可以触发我们在arrayMethods中的改写的数组操作方法。

缺陷:a、无法检测到对象属性的新增或删除。Vue2采用Vue.$set和Vue.$delete.

b、不能监听数组的变化。vue在实现数组的响应式时,它使用了一些hack,把无法监听数组的情况通过重写数组的部分方法来实现响应式,这也只限制在数组的push/pop/shift/unshift/splice/sort/reverse七个方法,其他数组方法及数组的使用则无法检测到。如直接修改值和获取数组长度。

Proxy,字面意思是代理,是ES6提供的一个新的API,用于修改某些操作的默认行为可以理解为在目标对象之前做一层拦截,外部所有的访问都必须通过这层拦截,通过这层拦截可以做很多事情,比如对数据进行过滤、修改或者收集信息之类。

ES6原生提供的Proxy构造函数,用法如下:

var proxy =new Proxy(obj, handler)

其中obj为Proxy要拦截的对象,handler用来定制拦截的操作,返回一个新的代理对象proxy;

vue3中利用Proxy实现数据读取和设置时进行拦截,在拦截trap中实现数据的依赖收集以及触发视图更新操作。

1)diff算法优化

diff算法是虚拟DOM技术的必然产物,它会对新旧虚拟DOM作对比(即diff),然后将变化的地方更新在真实DOM上。

在Vue2.0当中,当数据发生变化,它就会新生成一个DOM树,并和之前的DOM树进行比较,找到不同的节点然后更新。但这比较的过程是全量的比较,也就是每个节点都会彼此比较。但其中很显然的是,有些节点中的内容是不会发生改变的,那我们对其进行比较就肯定消耗了时间。

所以在Vue3.0当中,就对这部分内容进行了优化:在创建虚拟DOM树的时候,会根据DOM中的内容会不会发生变化,添加一个静态标记。那么之后在与上次虚拟节点进行对比的时候,就只会对比这些带有静态标记(patch flag)的节点。

patchFlag的类型:

patchFlag

2)hoistStatic 静态提升

vue2中无论元素是否参与更新,每次都会重新创建,然后再渲染;

vue3对于不参与更新的元素,会做静态提升,只会被创建一次,在渲染时直接复用即可。

3)cacheHandlers 事件侦听器缓存

默认情况下onClick会被视为动态绑定,所以每次都会去追踪它的变化。

但是因为是同一个函数,所以没有追踪变化,直接缓存起来复用即可

你可能感兴趣的:(Vue面试考点之Vue3)