vue render jsx(使用render函数渲染vue组件)

在 Vue 中,是如何基于渲染器来实现 vdom 渲染的呢?

/*** @param domString - DOM 节点信息* @param container - DOM 元素*/const renderer = (domString, container) => {  container.innerHTML = domString}renderer(\\\'<h1>Vue</h1>\\\', document.getElementById(\\\'app\\\'))

上面代码执行的逻辑是:把<h1>Vue</h1>字符挂载到 id 为 app 的 DOM 元素里。

这样就是一个最简单的渲染函数。

然后 Vue 基于上面的渲染函数,一层一层的封装,写分支,写语句,写循环。

renderer 是渲染器,render 是渲染。渲染器的意思就是将 vdom 渲染为真实 DOM。

vdom 和 vnode 可以混用,代表的都是一个意思。注:在真实 DOM 层面,Element 和 Node 是有区别的

翻了翻自己的文章记录,居然没找到 vdom 相关的文章 … 此处应该有一篇详细的 vdom 文章的链接。

渲染器把 vdom 节点渲染为真实 DOM 节点的过程称为「挂载」,英文用 mount 来表达。在 Vue 里,真实 DOM 挂载完成后,会触发 onMounted 钩子方法。所以,在 onMounted 钩子里可以访问到 DOM 元素。

function createRenderer() {  function render(vnode, container) {    if (vnode) {      //如果存在新的 vnode,那就需要 patch 一下      path(container._vnode, vnode, container)    } else {      if (container._vnode) {        //旧 vnode 存在,且新的 vnode 不存在,说明是 unmount 操作,需要将 dom 清空即可。        container.innerHTML = \\\'\\\'      }    }    container._vnode = vnode  }  return {    render  }}
const renderer = createRenderer()renderer.render(vnode, document.querySelector(\\\'#app\\\'))

在 Vue 中,用 createRenderer 函数来创建一个渲染器,函数内部封装了 render 方法。

我们来看个执行例子:

const renderer = createRenderer()//首次渲染renderer.render(vnode1, document.querySelector(\\\'#app\\\'))//第二次渲染renderer.render(vnode2, document.querySelector(\\\'#app\\\'))//卸载渲染renderer.render(null, document.querySelector(\\\'#app\\\'))

在「首次渲染」的时候,渲染器会把 vnode1 渲染为真实 DOM。渲染完成后 vnode1 内容会存储到 container._vnode 属性里,它就是后续渲染的旧vnode。

在「第二次渲染」的时候,旧 vnode 存在,渲染器会把 vnode2 作为新的 vnode,然后把新旧的 vnode 都传给 patch 函数进行打补丁。

在「卸载渲染」时,新 vnode 的值为 null,就是说不需要渲染 DOM,目前渲染的是 vnode2,所以渲染器会清空容器,上面代码中,暂时先用 container.innerHTML = \\’\\’ 来达到目的。

上面是 render 的逻辑,下面来简单刷下 patch 函数处理逻辑。

patch 函数承载了重要的渲染逻辑,就是常说的补丁、挂载、Diff算法等等,都是根据这个函数展开的,我们后续细写。

    const patch = (n1, n2, conatiner) => {  // ...}

    第一个参数 n1:旧 vnode;

    第二个参数 n2:新 vnode;

    第三个参数 container:挂载容器;

    第一次渲染时,容器的 container._vnode 属性是不存在的,会得到 undefined,也就是说传的第一个参数是 undefined,patch 会执行挂载逻辑,忽略 n1,直接把 n2 的内容渲染到容器中。

    当只有新元素时,渲染器直接执行挂载;当新旧内容都存在时,对比新旧 vnode 执行打补丁操作;当没有新元素时,则执行卸载。

    图片授权基于 www.pixabay.com 相关协议

    文章内容来源于《Vue.js 设计与实现》

    原创文章,作者:小道研究,如若转载,请注明出处:https://www.sudun.com/ask/34470.html

    (0)
    小道研究's avatar小道研究
    上一篇 2024年4月20日 下午2:18
    下一篇 2024年4月20日 下午2:20

    相关推荐

    发表回复

    您的邮箱地址不会被公开。 必填项已用 * 标注