mini-vue学习笔记

139 阅读2分钟

最近看了小崔的mini-vue视频教学,教程很nice,学过后担心忘的太快,故记录一些学习笔记,时时复习,代码已上传github mini-vue

小崔的Vue3源码实战课

重点内容如下

  • effect与reactive的实现
    • track 依赖收集 - 记录effect(fn)中的fn
    • trigger 触发依赖 - 执行effect(fn)中的fn
  • 初始化element
    • createApp -> mount -> createVnode -> render -> patch(核心) -> mountComponent -> createComponentInstance -> setupComponent -> setupRenderEffect
    • createApp对mount的包装
    • mount时创建根元素的vnode,而子节点的vnode会在后面执行render函数时创建
    • createVnode,返回一个普通对象vnode,供后续使用
    • patch内部判断vnode类型然后进行不同的处理,如果是element节点,直接创建dom节点并插入到container中
    • createComponentInstance,返回一个普通对象instance,供后续使用
    • setupComponent
      • initProps 把props挂载到instance上
      • initSlots 把object类型的slots挂载到instance上面,并对每个slot又进行了一层包裹,用于使slot的返回节点是array类型
      • setupStatefulComponent 执行setup函数,返回setupState,把render函数挂载到instance上
    • setupRenderEffect 执行instance.render,执行时用effect包裹render,收集依赖,同时把this指向instance.proxy,instane.unpdate = runner,获取subTree,subTree也是个vnode,然后递归调用patch,完成整个mount
  • 更新element
    • 赋值操作触发trigger -> 重新执行effect(render)中的render函数 -> patch(prevTree, subTree)
      • 更新普通dom节点
      • -> processElement -> patchChildren -> patchKeyedChildren(核心) -> patchProps
      • 更新组件
      • -> processComponent -> shouldUpdateComponent -> instance.update
    • patchKeyedChildren diff算法实现,处理dom移动时使用最大递增子序列算法实现最小移动步数
    • shouldUpdateComponent 组件主要判断props是否变化了,props如果变化则手动调用vnode.instance.update方法执行组件的render函数并patch
  • template解析
    • 解析 <div>hi: {{message}}</div>
    • baseParse(template) -> transform(ast) -> generate(ast)
    • baseParse
      • -> parseChildren(核心) -> parseElement -> parseChildren(递归) -> parseText -> parseInterpolation
      • 从左到右处理,处理了一部分就截取一部分,
      • parseChildren 执行while循环,退出标志是source.length为0,或者遇到了结束标签,维护一个栈,碰到开始标签入栈,处理完children出栈,chilren处理完了找不到结束标签就提前结束报错
    • transform
      • 遍历ast(递归),对每个节点执行nodeTransforms中的函数,类似于plugin
    • generate
      • 遍历ast(递归)生成代码,字符串代码