归档.md 2.7 KB

vue2 与 vue3 区别

  1. api不同 vue2 选项式 Opation API vue3 组合式 Component API
  2. 响应式不同 vue2: 基于Object.defineProperty(属性级)进行数据劫持,结合发布订阅模式实现; 数据劫持: Object.defineProperty会遍历data中所有的property 为每一个属性添加了getter和setter getter:读取属性时触发,依赖收集(记录那些地方用了什么属性,使用watch...) setter:修改属性时触发,通知更新(告诉依赖哪些地方需要重新计算,或渲染模版...) 发布-订阅模式: 依赖管理器:Dep: 每一个响应式属性维护一个Dep 订阅者:Watcher:关联到视图或者逻辑,当Dep告诉Watch更新,执行具体更新 流程: 1.初始:观察者(Observer)会遍历所有的data,用Object.defineProperty劫持所有属性,并给每个属性添加依赖管理器(Dep) 2.渲染: render函数会访问响应式属性,触发getter,Dep收集当前所有依赖,渲染Watcher 3.修改:触发setter方法,Dep通知所有订阅的Watch,执行更新 缺陷: 1.数据劫持局限:无法监听数组下标,方法,长度等等实现响应式,对数组处理有难度增加; 2.无法监听新增/删除属性:Object.defineProperty只能对初始化的数据进行数据劫持,如果动态增加或者删除属性,无法触发响应式,需要使用(Vue.set/Vue.delete)

vue3:

基于Proxy(对象级)去代理对象,配合Reflect去实现强大的响应式,结合依赖追踪和更新机制,但底层还是劫持方式实现;
数据劫持:
    Proxy包裹目标对象,拦截对象的所有操作
    get拦截: 读取属性时触发,依赖收集
    set拦截: 修改属性时触发,通知更新
    其他拦截(deletPropery,...):支持监听属性的删除...;
依赖管理:
    通过副作用(effect)收集依赖,track(追踪依赖)和tigger(触发更新)实现响应式更新;
流程:
    1.通过ref(reactive)创建响应式数据,返回Proxy代理后的对象;
    2.访问属性:Proxy中的get拦截器触发,tarck获取effect中当前的依赖;
    3.修改属性:Proxy中的set拦截器触发,tigger通知所有关联的effect执行更新;
优势:
    1.支持动态属性变化:Proxy直接代理整个对象,新增删除都可以被监听;
    2.数组劫持更自然:不需要重新数组,Proxy代理后可以直接进行数据操作,响应式更加彻底;
    3.性能优化:Proxy实现响应式,在初始化和更新时候都可以进行劫持数据,依赖被统一收集,减少代码的冗余;