主题列表:juejin, github, smartblue, cyanosis, channing-cyan, fancy, hydrogen, condensed-night-purple, greenwillow, v-green, vue-pro, healer-readable, mk-cute, jzman, geek-black, awesome-green
theme: vue-pro
highlight:
🔥这周我看了看了尤大神亲手写的mini版Vue3,笔记如下请大家指正。
⚡️关注公众号【前端大班车】 回复 【mini-vue】索取完整代码
一、整体工作流程
编译器将视图模板编译为渲染函数
数据响应模块将数据对象初始化为响应式数据对象
视图渲染
RenderPhase : 渲染模块使用渲染函数根据初始化数据生成虚拟Dom
MountPhase : 利用虚拟Dom创建视图页面Html
PatchPhase:数据模型一旦变化渲染函数将再次被调用生成新的虚拟Dom,然后做Dom Diff更新视图Html
二、三大模块的分工
数据响应式模块
编译器
渲染函数
1. 数据响应式模块
提供创建一切数据变化都是可以被监听的响应式对象的方法。
2. 编译模块
将html模板编译为渲染函数
这个编译过程可以在一下两个时刻执行
浏览器运行时 (runtime)
Vue项目打包编译时 (compile time)
3. 渲染函数
渲染函数通过以下三个周期将视图渲染到页面上
Render Phase
Mount Phase
Patch Phase
三、MVVM原型(Mock版)
MVVM框架其实就是在原先的View和Model之间增加了一个VM层完成以下工作。完成数据与视图的监听。我们这一步先写一个Mock版本。其实就是先针对固定的视图和数据模型实现监听。
1. 接口定义
我们MVVM的框架接口和Vue3一模一样。
初始化需要确定
视图模板
数据模型
模型行为 - 比如我们希望click的时候数据模型的message会会倒序排列。
const App = {
// 视图
template: `
{ {message}}
`,
setup() {
// 数据劫持
const state = new Proxy(
{
message: "Hello Vue 3!!",
},
{
set(target, key, value, receiver) {
const ret = Reflect.set(target, key, value, receiver);
// 触发函数响应
effective();
return ret;
},
}
);
const click = () => {
state.message = state.message.split("").reverse().join("");
};
return { state, click };
},
};
const { createApp } = Vue;
createApp(App).mount("#app");
2. 程序骨架
程序执行过程大概如图:
const Vue = {
createApp(config) {
// 编译过程
const compile = (template) => (content, dom) => {
};
// 生成渲染函数
const render = compile(config.template);
return {
mount: function (container) {
const dom = document.querySelector(container);
// 实现setup函数
const setupResult = config.setup();
// 数据响应更新视图
effective = () => render(setupResult, dom);
render(setupResult, dom);
},
};
},
};
3. 编译渲染函数
MVVM框架中的渲染函数是会通过视图模板的编译建立的。
// 编译函数
// 输入值为视图模板
const compile = (template) => {
//渲染函数
return (observed, dom) => {
// 渲染过程
}
}
简单的说就是对视图模板进行解析并生成渲染函数。
大概要处理以下三件事
确定哪些值需要根据数据模型渲染
// { {message}}
// 将数据渲染到视图
button = document.createElement('button')
button.innerText = observed.message
dom.appendChild(button)
绑定模型事件
// { {message}}
// 绑定模型事件
button.addEventListener('click', () => {
return config.methods.click.apply(observed)
})
确定哪