function renderer(domString, container) {
container.innerHTML = domString
}
const count = ref(1)
effect(() => {
renderer(`<h1>${count.value}</h1>`,
document.getElementById('app'))
})
count.value++
以上代码即为渲染器与响应系统的结合的大体原理,当然其中很多细节后面展现。
渲染器(renderer
)的作用是把虚拟DOM渲染为特定平台上的真实元素
其他都是一些概念,不再赘述
const vnode = {
type: 'h1',
children: 'hello'
}
// 在创建 renderer 时传入配置项
const renderer = createRenderer({
// 用于创建元素
createElement(tag) {
return document.createElement(tag)
},
// 用于设置元素的文本节点
setElementText(el, text) {
el.textContent = text
},
// 用于在给定的 parent 下添加指定元素
insert(el, parent, anchor = null) {
parent.insertBefore(el, anchor)
}
})
// 调用 render 函数渲染该 vnode
renderer.render(vnode, document.querySelector('#app'))
function createRenderer() {// 通过 options 得到操作 DOM 的 API
const {
createElement,
insert,
setElementText
} = options
function patch(n1, n2, container) {
// 如果 n1 不存在,意味着挂载,则调用 mountElement 函数完成挂载
if (!n1) {
mountElement(n2, container)
} else {
// n1 存在,意味着打补丁,暂时省略
}
}
function mountElement(vnode, container) {
// 调用 createElement 函数创建元素
const el = createElement(vnode.type)
if (typeof vnode.children === 'string') {
// 调用 setElementText 设置元素的文本节点
setElementText(el, vnode.children)
}
// 调用 insert 函数将元素插入到容器内
insert(el, container)
}
function render(vnode, container) {
if (vnode) {
patch(container._vnode, vnode, container)
} else {
if (container._vnode) {
container.innerHTML = ''
}
}
container._vnode = vnode
}
return {
render
}
}
上述代码是本章自定义一个渲染器的基本实现。