Virtual DOM

490 阅读2分钟

Snabbdom基本使用

  • 什么是虚拟dom

Virtual DOM(虚拟DOM) 是由普通的JS对象来描述DOM对象, 因为不是真实的DOM对象,所以叫Virtual DOM。

  • 虚拟dom的作用
    • 维护视图和状态的关系
    • 复杂视图的情况下提升渲染性能
    • 除了渲染DO以外,还可以实现SSR(Nuxt.js/Next.js)、原生应用(weex/rn) 小程序(mpvue/uniapp)

Snabbdom 常用模块

  • attrbutes
    • 设置DOM元素的属性, 使用setAttrbute()
    • 处理布尔类型的属性
  • props
    • 和attributes 模块相似, 设置DOM元素的属性element[attr] = value
    • 不处理布尔类型的属性
  • class
    • 切换样式
    • 注意: 给元素设置类样式是通过, sel选择器
  • dataset
    • 设置data-* 的自定义属性
  • eventlisteners
    • 注册和移除事件
  • style
    • 设置行内样式, 支持动画
    • delay/remove/destroy

模块使用

  • 模块使用步骤
    • 导入需要的模块
    • init()中注册模块
    • 使用h()函数创建VNode的时候, 可以把第二个参数设置为对象, 其他参数往后移
import { h, init } from 'snabbdom'
// 1.hello world 
// 参数: 数组, 模块
//  返回值: patch 函数, 作用对比两个vnode的差异更新到真实DOM 
let patch = init([])
// 第一个参数: 标签加选择器 
// 第二个参数: 如果是字符串的话就是标签中的内容
let vnode = h('div#container.cls', 'Hello World')
let app = document.querySelector('#app')
// 第一个参数: 可以是DOM, 内部会把DOM元素转换成vnode
// 第二个参数: vnode
// 返回值: vnode
let oldVnode = patch(app, vnode)
console.log(oldVnode)

h函数

  • h核心调用vnode()返回虚拟节点。
  • 在使用Vue的时候见过h()函数
    • h()函数最早见于hyperscript 使用JavaScript创建超文本
    • Snabbom 中的h()函数不是用来创建超文本的,而是创建Vnode
  • 函数重载
    • 概念参数或者类型不同的函数
    • Javascript中没有重载的概念
    • Typescript 中有重载, 不过重载的实现还是通过代码调整参数

vnode ()函数

patch() 的整体过程

  • patch(oldVnode VNode | Element, newVnode: VNode)
  • 打补丁,把新节点中变化的内容渲染到真实DOM,最后返回新节点作为下一次处理的旧节点
  • 对比新旧Vnode是否相同节点(节点的key 和 set 相同)
  • 如果不是相同节点,删除之前的内容重新渲染
  • 如果是相同的节点(key 和 sel 相同), 再判断新的Vnode是否有text,如果有并且和old的text不同,直接更新文本内容
  • 如果新的Vnode有children,判断子节点是否有变化, 判断子节点的过程就是使用diff算法