神族九帝's blog 神族九帝's blog
首页
网盘 (opens new window)
线报 (opens new window)
商城 (opens new window)
  • 复习指导
  • HTML
  • CSS
  • JavaScript
  • 设计模式
  • 浏览器
  • 手写系列
  • Vue
  • Webpack
  • Http
  • 前端优化
  • 项目
  • 面试真题
  • 算法
  • 精选文章
  • 八股文
  • 前端工程化
  • 基础篇
  • 进阶篇
  • 高级篇
  • 计算机基础
  • 高频考点
  • 精简题
  • 综合问题
  • 复习题
  • vue
  • vue2源码学习
  • 剖析vuejs内部运行机制
  • TypeScript 入门实战笔记
  • vue3源码学习
  • 2周刷完100道前端优质面试真题
  • npm发包
  • 重学node
  • 前端性能优化方法与实战
  • webpack原理与实战
  • webGl
  • 前端优化
  • Web3
  • 更多
  • 网站
  • 资源
  • Vue资源
  • 收藏的一些API
  • 未来要做的事
  • 宝塔面板+青龙面板
  • 安卓手机当服务器使用
  • 京东自动评价代码
  • 搭建x-ui免流服务器(已失效)
  • 海外联盟
  • 好玩的docker
  • 导航
GitHub (opens new window)

神族九帝,永不言弃

首页
网盘 (opens new window)
线报 (opens new window)
商城 (opens new window)
  • 复习指导
  • HTML
  • CSS
  • JavaScript
  • 设计模式
  • 浏览器
  • 手写系列
  • Vue
  • Webpack
  • Http
  • 前端优化
  • 项目
  • 面试真题
  • 算法
  • 精选文章
  • 八股文
  • 前端工程化
  • 基础篇
  • 进阶篇
  • 高级篇
  • 计算机基础
  • 高频考点
  • 精简题
  • 综合问题
  • 复习题
  • vue
  • vue2源码学习
  • 剖析vuejs内部运行机制
  • TypeScript 入门实战笔记
  • vue3源码学习
  • 2周刷完100道前端优质面试真题
  • npm发包
  • 重学node
  • 前端性能优化方法与实战
  • webpack原理与实战
  • webGl
  • 前端优化
  • Web3
  • 更多
  • 网站
  • 资源
  • Vue资源
  • 收藏的一些API
  • 未来要做的事
  • 宝塔面板+青龙面板
  • 安卓手机当服务器使用
  • 京东自动评价代码
  • 搭建x-ui免流服务器(已失效)
  • 海外联盟
  • 好玩的docker
  • 导航
GitHub (opens new window)
  • vue2源码学习

  • 剖析vuejs内部运行机制

    • Vuejs 运行机制全局概览
    • 响应式系统的基本原理
    • 响应式系统的依赖收集追踪原理
    • 实现 Virtual DOM 下的一个 VNode 节点
      • 什么是 VNode
      • 实现一个 VNode
    • template 模板是怎样通过 Compile 编译的
    • 数据状态更新时的差异 diff 及 patch 机制
    • 批量异步更新策略及 nextTick 原理
    • Vuex状态管理的工作原理
    • 总结 & 常见问题解答
  • TypeScript 入门实战笔记

  • vue3源码学习

  • 2周刷完100道前端优质面试真题

  • npm发包

  • 重学node

  • 前端性能优化方法与实战

  • webpack原理与实战

  • webGl

  • 前端优化

  • Web3

  • 更多

  • 学习笔记
  • 剖析vuejs内部运行机制
wu529778790
2021-11-12

实现 Virtual DOM 下的一个 VNode 节点

# 什么是 VNode

我们知道,render function 会被转化成 VNode 节点。Virtual DOM 其实就是一棵以 JavaScript 对象(VNode 节点)作为基础的树,用对象属性来描述节点,实际上它只是一层对真实 DOM 的抽象。最终可以通过一系列操作使这棵树映射到真实环境上。由于 Virtual DOM 是以 JavaScript 对象为基础而不依赖真实平台环境,所以使它具有了跨平台的能力,比如说浏览器平台、Weex、Node 等。

# 实现一个 VNode

VNode 归根结底就是一个 JavaScript 对象,只要这个类的一些属性可以正确直观地描述清楚当前节点的信息即可。我们来实现一个简单的 VNode 类,加入一些基本属性,为了便于理解,我们先不考虑复杂的情况。

class VNode {
  constructor(tag, data, children, text, elm) {
    /*当前节点的标签名*/
    this.tag = tag;
    /*当前节点的一些数据信息,比如props、attrs等数据*/
    this.data = data;
    /*当前节点的子节点,是一个数组*/
    this.children = children;
    /*当前节点的文本*/
    this.text = text;
    /*当前虚拟节点对应的真实dom节点*/
    this.elm = elm;
  }
}

比如我目前有这么一个 Vue 组件。

<template>
  <span class="demo" v-show="isShow">
    This is a span.
  </span>
</template>

用 JavaScript 代码形式就是这样的。

function render() {
  return new VNode(
    "span",
    {
      /* 指令集合数组 */
      directives: [
        {
          /* v-show指令 */
          rawName: "v-show",
          expression: "isShow",
          name: "show",
          value: true,
        },
      ],
      /* 静态class */
      staticClass: "demo",
    },
    [new VNode(undefined, undefined, undefined, "This is a span.")]
  );
}

看看转换成 VNode 以后的情况。

{
    tag: 'span',
    data: {
        /* 指令集合数组 */
        directives: [
            {
                /* v-show指令 */
                rawName: 'v-show',
                expression: 'isShow',
                name: 'show',
                value: true
            }
        ],
        /* 静态class */
        staticClass: 'demo'
    },
    text: undefined,
    children: [
        /* 子节点是一个文本VNode节点 */
        {
            tag: undefined,
            data: undefined,
            text: 'This is a span.',
            children: undefined
        }
    ]
}

然后我们可以将 VNode 进一步封装一下,可以实现一些产生常用 VNode 的方法。

  • 创建一个空节点
function createEmptyVNode() {
  const node = new VNode();
  node.text = "";
  return node;
}
  • 创建一个文本节点
function createTextVNode(val) {
  return new VNode(undefined, undefined, undefined, String(val));
}
  • 克隆一个 VNode 节点
function cloneVNode(node) {
  const cloneVnode = new VNode(
    node.tag,
    node.data,
    node.children,
    node.text,
    node.elm
  );
  return cloneVnode;
}

总的来说,VNode 就是一个 JavaScript 对象,用 JavaScript 对象的属性来描述当前节点的一些状态,用 VNode 节点的形式来模拟一棵 Virtual DOM 树。

注:本节代码参考《实现 Virtual DOM 下的一个 VNode 节点》 (opens new window)。

编辑 (opens new window)
上次更新: 2021/11/12, 22:24:53
响应式系统的依赖收集追踪原理
template 模板是怎样通过 Compile 编译的

← 响应式系统的依赖收集追踪原理 template 模板是怎样通过 Compile 编译的→

最近更新
01
好玩的docker
07-04
02
我的第一个NFT
07-03
03
海外迅雷
06-01
更多文章>
Power by vuepress | Copyright © 2015-2023 神族九帝
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×