第七章:渲染器的设计
渲染器的基本概念
- renderer:渲染器,其作用是把 虚拟 DOM 渲染成特定平台上的真实元素。
- render:动词,表示渲染。
- virtual DOM:虚拟 DOM,通常简写成 vdom
- virtual Node:虚拟节点,简写成 vnode,是 vdom 上的任何一个子树,因此 vdom 和 vnode 可以替换使用。
- mount:渲染器把 vdom 渲染成真实元素的过程称为 挂载
javascript
function createRenderer() {
function mountElement(vnode, container) {
const el = document.createElement(vnode.type);
if (typeof vnode.children === 'string') {
el.textContent = vnode.children;
}
container.appendChild(el);
}
/**
*
* @param n1 旧的 vnode
* @param n2 新的 vnode
* @param container 挂载的节点
*/
function patch(n1, n2, container) {
// 没有 n1 证明是第一次挂载
if (!n1) {
mountElement(n2, container);
} else {
// TODO:打补丁
}
}
function render(vnode, container) {
if (vnode) {
// 新 vnode 存在,将其与旧 vnode 一起传递给 patch 函数,进行打补丁
patch(container._vnode, vnode, container);
} else {
if (container._vnode) {
// 旧 vnode 存在,新的不存在,说明是卸载操作 - unmount
container.innerHTML = '';
}
}
container._vnode = vnode;
}
return {
render
};
}
const rendered = createRenderer();
rendered.render(vnode, document.querySelector('#renderId'));
自定义渲染器
可以在创建渲染器时将一些基础操作传入
javascript
function createRenderer(options) {
const { createElement, setElementText, insert } = options;
function mountElement(vnode, container) {
const el = createElement(vnode.type);
if (typeof vnode.children === 'string') {
setElementText(el, vnode.children);
}
insert(el, container);
}
function patch(n1, n2, container) {
/** */
}
function render(vnode, container) {
/** */
}
return {
render
};
}
const rendered = createRenderer({
createElement(tag) {
return document.createElement(tag);
},
setElementText(el, text) {
el.textContent = text;
},
insert(el, parent, anchor = null) {
parent.insertBefore(el, anchor);
}
});