Vue3巧妙的初始化流程解析

487 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情

前言

最近摸鱼时间较多,随手想到了前一段时间了解的vue3,在vue3中初始化和vue2初始化大不一样,不会在使用new Vue()进行初始化,vue3初始化已改为CareteApp(),接下来咱们主要说下vue3的初始化机制是怎样的

动机

  • 类型支持更好
  • 利于tree-shaking
  • 简化API、一致性:render函数、sync修饰符、指令定义等
  • 复用性:有强大的composition Api
  • 性能有很大提升(响应式、编译优化)
  • 扩展:自定义渲染器 image.png

基本结构

createApp创建Vue实例时,它拥有一个mount()方法负责初始化,mount()方法在createApp()中

let vue3 = {
    createApp(options) {
     return {
         mount(selector) {}
    }
  }
}

挂载

  • 将传入的根组件配置转换为Dom并追加到当前元素上$parent,selector参数为当前的元素
mount(selector) {
    const parent = document.querySelector(selector);
}
  • 获取render函数,并进行判断,如果不为空则返回一个render函数,parent.innerHTML为当前模板内容
if (options.render) {
    options.render = this.compile(parent.innerHTML);
}
  • 进行渲染Dom,并且要加到当前元素上
  1. 把当前模板内容设置为空
parent.innerHTML = "";
  1. 加到当前元素上,使用appendChild()方法,并把当前optionsData传入到render里进行处理;
parent.appendChild(options.render.call(options.data()));
  1. 把模板转为渲染函数,compile为render渲染函数它接收一个模板,并把它返回出去!render函数内为具体的元素内容,最后把给这个元素赋值,并返回出去
compile(template) {
    return function render() {
        return document.createElement(xx).textContent = 'xx'
    }
}

兼容vue2

如果用户时setup的写法,就应该先执行setup(),然后进行处理其他的选项,这样就很方便的兼容了vue2的api

if (options.setup) {
    this.setupState = options.setup();
} else {
    this.data = options.data();
}

判断setup这样就能精准赋值!

创建一个proxy对象,实现操作和拦截,proxy对象由两部分组成,target、handler;get()读取拦截的对象和set()设置拦截对象的属性并返回一个状态(成功or失败)

new Proxy(this, {
    get(target, key) {
      if (key in target.setupState) {
        return target.setupState[key];
      } else {
        return target.data[key];
      }
    },
    set(target, key, val) {
      if (key in target.setupState) {
        target.setupState[key] = val;
      } else {
        target.data[key] = val;
      }
     },
});

在get和set内咱们分别在读取和设置了对象val,进行了精准判断setUp状态和赋值,并进行返回处理

最后调用将模板转换成渲染函数render并挂载

options.render.call(new Proxy())

总结

这里展示了最基础的初始化流程,vue3中的createApp方法学习过程中感觉非常绕,但是在看完后,又马上忘记了,难!!!下一步继续学习vue3的核心部分:响应式,并进行巩固。