zhangzheng-zz / blog

1 stars 0 forks source link

vue源码 #20

Open zhangzheng-zz opened 3 years ago

zhangzheng-zz commented 3 years ago

compile 的结果

vue2 vs vue3

1、响应式: vue2 深度劫持,消耗大,对对象属性,数组的劫持能力 2、全局:vue2方法(use、mixin)挂载在Vue全局,vue3分包分模块,tree-shaking,将响应式API reactive 暴露。 3、编译:vue2不分静态动态模板从头diff,vue3定向diff,静态提升序列化成字符串 4、options Api composition API

vue3 diff

patchElement -> patchChildren 类型不一样的节点旧直接卸载 patch 孩子的时候 text null array 核心 patch array 从头比对 从尾比对 一方结束的情况: 新短旧长,从头/尾卸载旧 新长旧短,从头/尾渲染新 乱序:

vue2 diff

头头比对 尾尾比对 交叉比对 头尾比对 移除与更新

调度

nextTick 的实现就是将回调 fn 放到清空当前任务 flushJobs 之后 p.then(flushJobs)包装之后成为微任务。 当前任务是指queueJob里面的任务,包括了DOM的更新 调度: 维护三个队列,在DOM各个时期将相应的任务入队。flushJobs是清空队列的方法,经过 promise.then(f) DOM的更新是一个effect副作用函数,在trigger的时刻会触发这个副作用,effect判断有传入调度器, 不会立刻执行effect,而是放入队列,等待异步执行。队列会去重。防止重复执行。(渲染)****

zhangzheng-zz commented 2 years ago
export default function Console (BaseComponent) {
  return {
    mounted () {
      console.log('HOC')
    },
    props: BaseComponent.props,
    render (h) {
      const slots = Object.keys(this.$slots).reduce((acc, key) => acc.concat(this.$slots[key]), [])
        .map(vnode => {
          // 将slot透传 slot 中的 VNode 的context 引用的还是原来的父组件实例,context应该引用的是高阶组件 
          // 导致了使不使用具名插槽都一样,最后都是按默认插槽来处理的
          // this._self 指向 HOC 实例
          vnode.context = this._self
          return vnode
        })
      return h(
        BaseComponent,
        {
          on: this.$listeners,
          props: this.$props,
          // 作用域插槽 slot 可以访问父作用域中的数据
          scopedSlots: this.$scopedSlots,
          attrs: this.$attrs
        },
        slots
      )
    }
  }
}
zhangzheng-zz commented 2 years ago

vue 2 vs vue3 应用: 1、composition api vs options api 将API和功能逻辑抽离成块,方便定位 2、全局属性和实例属性 Vue (use\mixins) app (use\mixins) 3、setup的使用,替代 beforeCreate created 内部没有this对象 4、响应式的 api ref reactive vs data 对象 源码: 1、响应式的实现,设计模式一致,观察者发布订阅模式, 编码实现不同 Object.definePrototype 增删Key 深度嵌套(递归) Proxy vue2 Dep 发布者 Watcher 观察者 在 Watch 中 Dep.target = this [建立依赖] get 触发依赖联系 vue3 effect 触发依赖联系 2、vue3 具有对模板分为静态和动态,具有静态提升 HOISTED 静态节点超过6个的话就会直接字符串化 提高 diff 效率 diff 算法实现不一致 3、nextTick 对低版本放弃兼容 4、vue3 模块分包,tree-shaking, vue2 的方法都是挂载在实例上面 5、加入 patchFlags 标记节点类型 分别执行不同的 patch (process) 没有标记就是 full diff

编译时: parse(ast) -> transform(遍历ast,节点标记等) -> generrate(code 字符串传递给 render 函数,render 的产出是 vnode) 运行时: render产出的 vnode 输出DOM渲染,vnode 的 diff, 生命周期与调度等内容 响应式: 响应式更新

观察者与发布订阅者不同 观察者中 发布者和订阅者(观察者)是相互依赖的 必须要求观察者【订阅内容改变事件】 , 而发布订阅者是由【调度中心】进行调度,那么看看观察者模式 是如何【相互依赖】。