• vue3初始化过程(实例创建和挂载)



    theme: channing-cyan

    实例创建,实例挂载

    1. vue-3.2.30\packages\vue\examples\composition新建test.html文件,内容如下:
    <script src="../../dist/vue.global.js"></script>
    <div id="demo">
      <section>
        <h1>{{count}}</h1>
      </section>
    </div>
    <script>
      const { createApp, ref } = Vue
      var app = createApp({
        setup() {
          const count = ref(1)
          return { count }
        }
      })
      app.mount('#demo')
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    1. 按住ctrl + p,输入runtime-core/src/apiCreateApp.ts,回车找到该文件
    2. 按住ctrl + f,输入function createAppAPI,回车找到该文件位置,在浏览器中给该位置打断点
    //用户执行了创建实例代码,其实是为了得到app实例对象,就是执行了一下函数createAppAPI内部返回的createApp方法,且返回app实例,app实例是一个对象,上面也挂载了mount等方法
     var app = createApp({})
    
    • 1
    • 2
    1. 按住ctrl + f,输入const vnode = createVNode(,回车找到该文件位置,在浏览器中给该位置打断点
    2. 按住ctrl + f,输入render(vnode, rootContainer, isSVG),回车找到该文件位置,在浏览器中给该位置打断点
    // 当执行挂载方法 就会触发步骤4 和 步骤5的断点
    app.mount('#demo')
    
    • 1
    • 2
    1. 按住ctrl + p,输入runtime-core/src/renderer.ts,回车找到该文件
    2. 按住ctrl + f,输入createAppAPI(render, hydrate),回车找到该文件位置,按住ctrl+左键点击render函数,找到render函数的声明的位置
    3. 按住ctrl + f,输入patch(container._vnode,回车找到该文件位置,打上断点
    const render = (vnode, container, isSVG) => {// 首次vnode有值
      if (vnode == null) {
        if (container._vnode) {
          unmount(container._vnode, null, null, true)
        }
      } else { // 首次container._vnode 没有值
        patch(container._vnode || null, vnode, container, null, null, null, isSVG)
      }
      flushPostFlushCbs()
      container._vnode = vnode // 首次container._vnode被赋值,供给下一次使用
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    1. 按住ctrl + 左键,点击patch函数,找到patch函数声明的位置
    2. 按住ctrl + f,输入processElement(,回车找到该文件位置,打上断点
    3. 按住ctrl + f,输入processComponent(,回车找到该文件位置,打上断点
    4. 只留步骤10 和 步骤11两个断点,刷新页面,点击Resume script execution,可以看到patch的递归过程
    5. 按住ctrl + f,输入createComponentInstance(,回车找到该文件位置,打上断点,创建实例
    6. 按住ctrl + f,输入setupComponent(instance),回车找到该文件位置,打上断点,初始化工作执行setup,并且将结果响应式化
      • initProps
      • initSlots
      • setupStatefulComponent
    7. 按住ctrl + f,输入setupRenderEffect( , 回车找到该文件位置,打上断点,
    8. 按住ctrl + p,输入runtime-core\src\component.ts,回车找到该文件,
    9. 按住ctrl + f,输入proxyRefs(setupResult),回车找到该文件位置,打上断点,将setup函数执行的结果setupResult,做代理,然后赋值给instance.setupState
      浓缩版代码流程
    const createApp = function(...args){
        const app = ensureRenderer().createApp(...args)
        const mount = app.mount
        app.mount = function(v){
            return mount(v)
        }
        return app
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    let renderer;
    function ensureRenderer(){
        return (renderer || renderer = createRenderer())
    }
    
    • 1
    • 2
    • 3
    • 4
    function createRenderer(){
        return baseCreateRenderer()
    }
    
    • 1
    • 2
    • 3
    function baseCreateRenderer(){
        const render = (vnode,container,isSVG){
            if(vnode == null){
                if(container._vnode){
                    unmount(container._vnode,null,null,true)
                } else{
                    patch(container._vnode || null,vnode,container,null,null,null,isSVG)
                }
            }
        }
        return {
            render,
            createApp:createAppAPI(render) // createApp()时,就会执行createAppAPI函数
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    function createAppAPI(render){
        const context = createAppContext()
        return function createApp(rootComponent,rootProps = null){ // createApp()时,返回app
            const app = (context.app = {
                mount(rootContainer){// 等到用户调用了app.mount()才会执行内部的mount函数
                    const vnode = createVNode(
                        rootComponent,
                        rootProps
                    )
                    render(vnode,rootContainer,isSVG)
                }
            })
            return app 
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    流程图

    在这里插入图片描述

    vue3源码流程图 | ProcessOn在线思维导图

    vue3源码流程图 - ProcessOn

  • 相关阅读:
    7-6 静静的推荐
    大学生端午节网页作业制作 学生端午节日网页设计模板 传统文化节日端午节静态网页成品代码下载 端午节日网页设计作品
    系统软件开发基础知识
    如何从0开发一个Vue组件库并发布到npm
    iPhone没有收到iOS16最新版的推送,如何升级系统?
    Flask框架配置Celery-[2]:将前端上传的文件,通过异步任务保存,异步处理上传的文件
    C. Labs
    slam学习 - 基本VO代码学习
    Redis趋势—NVM内存
    Python爬虫学了几个月却不敢接单?过来人的经验总结收好!
  • 原文地址:https://blog.csdn.net/formylovetm/article/details/125560106