虚拟DOM

虚拟DOM是一种通过JS对象描述DOM的技术,用于优化重绘和重排,提升前端性能。本文详细介绍了虚拟DOM的使用,包括Snabbdom的安装、初始化、h函数、VNode、patch函数等关键概念,并阐述了其在处理复杂视图和状态管理中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

虚拟DOM

通过普通的JS对象来描述DOM对象 ,解决重绘和重排性能开销问题。
作用:维护视图和状态的关系;复杂视图情况下提升渲染性能;首次渲染会增加开销

使用虚拟DOM

  1. 安装Parcel npm i parcel-bundler -D
  2. 安装引入snabbdom npm i snabbdom
  3. 引入snabbdom中的init 和 h 模块
//通过h函数创建 VNode。h函数第一个参数:标签+选择器;第二个参数:如果是字符串就是标签中的内容
let vNode = h('div#box.container','默认内容')
// 获取挂载元素
const dom = document.querySelector('#app')
// 通过init 函数得到patch函数,patch函数第一个参数:旧的VNode,可以是DOM元素,第二个参数是新的VNode,返回新的Vnode
const patch = init([])
// 通过patch,将vNode渲染到Dom
let oldvNode = patch(dom, vNode)
// 创建新的vNode,更新给oldVnode
vNode = h('div#vNode','这是p标签的内容')// 包含单个节点的vNode
vNode1 = h('div#vNodes', [
  h('h1','标题内容')
  h('p','文本内容')
])
patch(oldvNode, vNode)  //挂载单标签元素
patch(oldvNode, vNode1) //挂载含子节点的元素
patch(oldvNode, h('!')) //代表注释节点,清空所有内容

模块使用

Snabbdom核心库不能操作DOM元素的样式、事件、和属性,可以通过默认提供的模块实现。模块实现通过注册全局的钩子函数实现。

官方提供模块
  1. attributes 可以处理布尔值;设置vnode的DOM属性使用setAttribute实现
  2. props 不可处理布尔值;设置DOOM对象的属性,通过对象.属性方式实现
  3. dataset 处理data-的属性
  4. class 类模块处理,切换类样式
  5. style 行内样式设置,可设置过渡动画
  6. eventlisteners 监听器模块,注册和移除事件
模块操作步骤
  1. 导入模块(引入的名称必须与导出时一致)
  2. init()注册模块,参数是数组,将注册的模块放入到数组中
  3. h()第二个参数使用模块
import { init } from 'snabbdom/build/package/init'
import { h } from 'snabbdom/build/package/h'
// 1 导入模块
import { styleModule } from 'snabbdom/build/package/modules/style'
import { eventListenersModule } from 'snabbdom/build/package/modules/eventlisteners'
// 2 注册模块(为 patch 函数添加模块对应的能力)
const patch = init([
  styleModule,
  eventListenersModule
])
// 3 使用模块
let vNode = h('div#box', {
  style: {
    backgroundColor: 'green',
    height: '200px',
    width: '200px'			//样式必须添加单位
  }
}, [
  h('h1#title', {
    style: {
      color: '#fff'
    },
    on: {
      click () {
        console.log('点击了 h1 标签')
      }
    }
  }, '这是标题内容'),
  h('p', '这是内容文本')
])
const dom = document.getElementById('app')
patch(dom, vNode)

h函数:创建节点并可设置子元素

vm.$createElement(tag,data,children,normalizeChildren) 实现。使用typescript中的函数重载,给不同的数量和类型的参数设置不同的实现。h('标签+选择器','text')第二个参数如果是字符串就是标签中的内容。如果是包含子元素则为数组。返回VNode对象

let vnode = h('div#container',[h('h1','Hello'),h('p','这是一个p标签')])
patch(vnode,h('!'))	//h('!')设置为空的注释节点

VNode函数

作用:渲染节点

patch函数

作用:新旧节点比对,页面虚拟节点设置
语法:patch(oldVnode,newVnode)

  1. 将新节点中变化的内容渲染到真实DOM,最后返回新节点作为下一次处理的旧节点
  2. 对比新旧VNode是否相同节点(节点的key和sel相同)如果不是相同节点删除之前的内容重新渲染;如果是相同节点在判断新的VNode是否有text如果有并且和oldVnode的text不同,直接更新文本内容
  3. 如果新的VNode有children判断子节点是否有变化

init函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值