Vue3渲染器

基本概念

渲染器的作用是把虚拟DOM渲染为特定平台上的真实元素。利用响应系统的能力,可以自动调用渲染器完成页面的渲染和更新。渲染器的重点是精确地找到vnode对象的变更点并只更新变更的内容。

挂载(mount):把虚拟DOM节点渲染为真实DOM节点的过程
更新(patch):将newVNode与上一次渲染的oldVNde进行对比,找到并更新变更点

实现思路

大概流程
通过createRenderer来创建渲染器,渲染器中包含render渲染函数

function createRenderer() {
   
  function render() {
   
    // ...
  }
  return {
   
    render
  };
}

进行渲染时,除了要执行挂载动作外,还要执行更新、卸载动作

const renderer = createRenderer();
// 首次渲染 挂载
renderer.render(vnode1, document.querySeelct("#app"));
// 第二次渲染 打补丁
renderer.render(vnode2, document.querySeelct("#app"));
// 第三次渲染 卸载
renderer.render(null, document.querySeelct("#app"));

实际上挂载也可以看作是一种特殊的打补丁(patch),所以render的基本实现

function render(vnode, container) {
   
  if (vnode) {
   
    // 存在新vnode container._vnode: 容器原本的vnode节点
    patch(container._vnode, vnode, container);
  } else {
   
    if (container._vnode) {
   
      // 存在旧vnode,不存在新vnode。卸载操作
      unmount(container._vnode);
    }
  }
  // 后续渲染中的旧vnode
  container._vnode = vnode;
}

patch函数

/**
 * 渲染核心
 *
 * @export
 * @param {*} n1 旧vnode
 * @param {*} n2 新vnode
 * @param {*} container 容器
 */
function patch(n1, n2, container) {
   
  if (!n1) {
   
    // 不存在旧的节点,挂载
    mountElement(n2, container, anchor);
  } else {
   
    // 存在旧节点,更新
    patchElement(n1, n2);
  }
}

挂载节点和元素的属性

一个虚拟节点的数据结构为:type标识标签名,children可能为数组或普通字符串

const vnode = {
   
  type: 'div',
  props: {
   
  	id: 'foo'
  },
  children: [
    {
   
      type: 'p',
      children: 'hello'
    }
  ]
}

挂载元素

vnode.type的值作为标签名来创建DOM元素

function mountElement(vnode, container, anchor) {
   
  const el = createElement(vnode.type));

  if (typeof vnode.children === "string") {
   
  	// 设置文本
    setElementText(vnode.children);
  } else if (Array.isArray(vnode.children)) {
   
    // 存在子节点
    vnode.children.forEach((child
  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值