一、vue响应式原理

1.原理:vue.js是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty(vue2)劫持各个属性的getter、setter。当数据发生改变时,发布消息给订阅者,触发相应的监听回调来渲染视图。

2.具体步骤:

    1. 需要Observe的对象进行递归遍历,包括子属性对象的属性,加上getter、setter。这样的话给某个属性赋值的时候就会触发setter,那么就能监听到数据的变化。
    1. Compile解析模板指令,将模板中的变量替换成数据。然后初始化渲染页面视图,并将每个指定该对应的节点绑定更新函数。添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图。
    1. Watcher订阅者是Observe和Compile之间通信的桥梁,主要做的事情有:(1)在自身实例化时往属性订阅器(dev)里面添加自己。(2)自身必须有一个update()方法.(3)待属性变动dep.notice()通知时,能调用自身的update()方法,并触发Compile中绑定的回调,则功成身退。
    1. MVVM作为数据绑定的入口,整合Observe、Compile、Watcher三者,通过Observe来监听自己model数据变化,通过Compile解析翻译模板指令,最终利用Watcher搭起Observe和Compile之间的通信桥梁,达到双向绑定效果。(数据变化 => 更新视图;视图交互变化(input)=> 数据model变更)

二、Object.defineProperty

1.语法:

  Object.defineProperty(obj, prop, descriptor) 

1.obj:必需。 目标对象
2.prop:必需。需定义或修改的属性的名字
3.descriptor:必需。目标属性所拥有的特性方法

2.缺陷

1.object.defineProperty无法发现属性的新增或者删除,除非用Vue.set()方法,但是它底层其实也是调用了object.defineProperty方法的。

2.还有当数组的长度发生改变无法检测到数组的变动。

3.以及当对象多层嵌套的时候object.defineProperty去递归遍历的话性能开销较大,而proxy的话是调用的时候再去遍历就节约性能很多。

二、Proxy

1.定义:Proxy可以理解成,在目标对象之前架设一层 "拦截",当外界对该对象访问的时候,都必须经过这层拦截,而Proxy就充当了这种机制,类似于代理的含义,它可以对外界访问对象之前进行过滤和改写该对象

2.语法:

  const obj = new Proxy(target, handler)
  被代理之后返回的对象 = new Proxy(被代理对象,要代理对象的操作)

handler中常用的对象方法如下:

1. get(target, propKey, receiver)
2. set(target, propKey, value, receiver)
3. has(target, propKey)
4. construct(target, args):
5. apply(target, object, args)

3.缺陷

对IE不友好,所以vue3在检测到如果是使用IE的情况下(没错,IE11都不支持Proxy),会自动降级为Object.defineProperty的数据监听系统。

原文链接:https://blog.csdn.net/weixin_38318244/article/details/123601856