mini-Vue
前置知识
- Vue中使用了虚拟DOM。
The virtual DOM (VDOM) is a programming concept where an ideal, or “virtual”, representation of a UI is kept in memory and synced with the “real” DOM by a library such as ReactDOM. This process is called reconciliation. – React官方文档
可以看到 React 也使用了虚拟 DOM 😃
虚拟DOM(VDOM)是一种编程概念,其中UI“虚拟”表示保存在内存中,并通过ReactDOM之类的库与“真实”DOM同步。
- 虚拟 DOM 可以为我们带来什么?
-
操作便利:因为对于直接操作DOM来说是有很多的限制的,比如diff、clone等等,但是使用JavaScript编程语言来操作这
些,就变得非常的简单;
-
性能优势:频繁的操作真实 DOM 会在性能方面造成极大的损耗,我们可以采用 虚拟 DOM 中的 diff 算法渲染真实DOM,提升了性能。
-
跨平台性:可以将VNode节点渲染成任意你想要的节点,如渲染在canvas、WebGL、SSR、Native(iOS、Android)上,并且Vue允许你开发属于自己的渲染器(renderer),在其他的平台上渲染;
Vue主要由哪几部分构成?
- Compiler模块:编译模板系统;
- Runtime模块:也可以称之为Renderer模块,真正渲染的模块;
- Reactivity模块:响应式系统;
Vue工作流程
- 通过
h
函数创建出 vnode (虚拟节点) - 如果没啥变化,直接渲染上去
- 当数据被修改了,会创建一个 newVnode,通过 diff 算法与 oldVnode 进行比对,然后进行渲染。
Part One 渲染器的实现
该模块主要包括三个功能
- h函数,用于返回一个VNode对象;
- mount函数,用于将VNode挂载到DOM上;
- patch函数,用于对两个VNode进行对比,决定如何处理新的VNode;
// 首先实现h函数,h函数就是为了让我们返回一个 JavaScript 对象的,则:
const h = (tag, props, children) => {
return {
tag,
props,
children
}
}
// 其次我们需要实现一个 mount 函数,将我们的虚拟节点转化成真实的节点,并且挂载到container上
const mount = (vnode, container) => {
// 1. 创建出真实的原生,并在 vnode 上保留 el
const el = vnode.el = document.createElement(vnode.tag)
// 2. 处理 props
if(vnode.props) {
for(const key in vnode.props) {
// 获取值
const value = vnode.props[key]
// 如果是事件的话
if(key.startsWith("on")) {
el.addEventListener(key.slice(2).toLowerCase(), value)
} else {
// 如果只是属性的话
el.setAttribute(key, value);
}
}
}
// 3. 处理 chilren
if(vnode.chilren) {
if(typeof vnode.chilren === "string") {
el.textContent = vnode.children
} else {
vnode.chilren.forEach((item) => {
mount(item, el)
})
}
}
}
// 最后就是要实现一个进行 diff 比对的 patch 函数