一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情。
前言
最近摸鱼时间较多,随手想到了前一段时间了解的vue3,在vue3中初始化和vue2初始化大不一样,不会在使用new Vue()进行初始化,vue3初始化已改为CareteApp(),接下来咱们主要说下vue3的初始化机制是怎样的
动机
- 类型支持更好
- 利于tree-shaking
- 简化API、一致性:render函数、sync修饰符、指令定义等
- 复用性:有强大的composition Api
- 性能有很大提升(响应式、编译优化)
- 扩展:自定义渲染器
基本结构
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,并且要加到当前元素上
- 把当前模板内容设置为空
parent.innerHTML = "";
- 加到当前元素上,使用
appendChild()方法,并把当前optionsData传入到render里进行处理;
parent.appendChild(options.render.call(options.data()));
- 把模板转为渲染函数,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的核心部分:响应式,并进行巩固。