mini-vue
小于 1 分钟
前言
基于前几节的实现,现在已经可以搭建一个 vue 的雏形了。
现在需要实现一个 mount
函数来挂载整个 app
思路
该函数接收两个参数,一个是 App(组件),一个是要挂载到的节点
App对象
上要有响应式数据,并且要有 虚拟 dom
,当虚拟dom依赖的响应式数据发生变化时(即被 watchEffect函数
监听到),对比 新旧虚拟 dom
。
watchEffect(()=>{
if 未挂载
渲染虚拟 dom
挂载真实 dom
else 已挂载
重新渲染虚拟 dom
比较新旧虚拟 dom
替换掉旧虚拟 dom
})
实现
App
const App = {
data:reactive({
count:0
}),
render(){
return {
'div',
{
onClick:()=>{this.data.count++}
},
String(this.data.count) // vue 编译器会对非 array 类型的数据做字符串转换
}
}
}
mount
function mount(component, container) {
let isMounted = false;
let preDom;
watchEffect(() => {
if (!isMounted) {
preDom = component.render();
mountDom(preDom, container);
isMounted = true;
} else {
const newDom = component.render();
patch(preDom, newDom);
preDom = newDom;
}
});
}
挂载 App
mount(App, document.getElementById("app"));
总结
至此,就实现了一个简易版的 vue,符合 MVVM
模式, Model - view - viewModel,定义数据,定义视图,数据修改时通过 vm 驱动视图更新。