IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> Vue Virtual DOM(虚拟DOM)、使用Snabbdom模拟虚拟DOM实现原理 -> 正文阅读

[JavaScript知识库]Vue Virtual DOM(虚拟DOM)、使用Snabbdom模拟虚拟DOM实现原理

什么是 Virtual DOM

  • Virtual DOM(虚拟 DOM),是由普通的 JS 对象来描述 DOM 对象
  • 使用 Virtual DOM 来描述真实 DOM
    在这里插入图片描述

为什么要使用 Virtual DOM

  • 前端开发刀耕火种的时代
  • MVVM 框架解决视图和状态同步问题
  • 模板引擎可以简化视图操作,没办法跟踪状态
  • 虚拟 DOM 跟踪状态变化
    • 虚拟 DOM 可以维护程序的状态,跟踪上一次的状态
    • 通过比较前后两次状态差异更新真实 DOM

虚拟 DOM 的作用和虚拟 DOM 库

虚拟 DOM 的作用

  • 维护视图和状态的关系
  • 复杂视图情况下提升渲染性能
  • 跨平台
    • 浏览器平台渲染DOM
    • 服务端渲染 SSR(Nuxt.js/Next.js)
    • 原生应用(Weex/React Native)
    • 小程序(mpvue/uni-app)等

虚拟 DOM 库

  • Snabbdom
    Vue.js 2.x 内部使用的虚拟 DOM 就是改造的 Snabbdom
    大约 200 SLOC (single line of code) (源码大约就200行,所以研究虚拟DOM使用Snabbdom比研究Vue源码轻松)
    通过模块可扩展(功能强大,类似于插件机制)
    源码使用 TypeScript 开发
    最快的 Virtual DOM 之一
  • virtual-dom

Snabbdom 基本使用

创建项目

安装 parcel

  1. 创建项目目录
md snabbdom-demo
  1. 进入项目目录
cd snabbdom-demo
  1. 创建package.json
npm init -y
  1. 本地安装parcel
npm install parcel-bundler -D

注意:以上操作在 管理员身份运行的cmd窗口中操作,否则可能会在最后一步报错

配置 scripts

安装 parcel 之后,项目目录结构如下
在这里插入图片描述

"scripts": {
    "dev": "parcel index.html --open",
    "build": "parcel build index.html"
  },

目录结构

  1. 根目录下创建入口文件index.html
  2. 创建src目录
    在这里插入图片描述

Snabbdom 文档

  • 看文档的意义
    学习任何一个库都要先看文档
    通过文档了解库的作用
    看文档中提供的示例,自己快速实现一个 demo
    通过文档查看 API 的使用
    (以上题外话_~~~下面提供一个地址感兴趣的阔以看看)
    https://github.com/snabbdom/snabbdom
  • 当前版本 v2.1.0

导入 Snabbdom

创建完项目之后,要导入 Snabbdom

安装 Snabbdom

 npm install snabbdom@2.1.0

导入 Snabbdom

  • Snabbdom 的两个核心函数 init 和 h()
    • init() 是一个高阶函数,返回 patch()
    • h() 返回虚拟节点 VNode
补充
  • 文档中导入的方式
    在这里插入图片描述
  • 实际导入的方式
    parcel/webpack 4 不支持 package.json 中的 exports 字段
    在这里插入图片描述

Demo

通过使用Snabbdom 模拟演示虚拟DOM的实现原理
index.html 引入 01-basicusage.js

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Snabbdom-demo</title>
</head>
<body>
    <div id="app"></div>
    <script src="./src/01-basicusage.js"></script>
</body>
</html>

01-basicusage.js

  • init函数(返回一个patch函数)作用:把虚拟 DOM 转化为真实 DOM 并挂载到 DOM树上
  • h函数作用:创建虚拟 DOM,这里创建的是 VNode 虚拟节点
  • vnode作用:描述真实 DOM
import { init } from 'snabbdom/build/package/init'
import { h } from 'snabbdom/build/package/h'

const patch = init([])

/**
 * init函数(patch函数)作用:把虚拟 DOM 转化为真实 DOM 并挂载到 DOM树上
 * h函数作用:创建虚拟 DOM,这里创建的是 vnode 虚拟节点
 * vnode作用:描述真实 DOM
 */

/**
 * h函数参数
 * 第一参数:标签+选择器
 * 
 * 第二个参数:
 * 如果是字符串就是标签中的文本内容
 * 如果想要嵌套子元素,则第二个参数是一个数组,数组中每个成员都是一个h函数
 *  
*/
// 创建一个vnode h('标签名#id.class')
let vnode = h('div#container.cls','Hello World')
// 获取页面上的id为app的div
let app = document.querySelector('#app')
// 调用patch 比较两个vnode,把两个vnode的差异更新到真实DOM上
/**
 * patch函数参数
 * 第一个参数:旧的 VNode,也可以是 DOM 元素
 * 第二个参数:新的 VNode
 * 
 * 返回值:返回一个新的 VNode,也就是第二个参数
 * 返回的新 VNode 会作为下一次再调用patch时 旧的 VNode 即 把当前的状态保存起来
 */
let oldVnode = patch(app, vnode)

vnode = h('div#container.xxx','Hello Snabbdom')
patch(oldVnode, vnode)

运行

npm run dev

浏览器执行结果
在这里插入图片描述
index.html 引入 02-basicusage.js

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Snabbdom-demo</title>
</head>
<body>
    <div id="app"></div>
    <script src="./src/02-basicusage.js"></script>
</body>
</html>

02-basicusage.js

import { init } from 'snabbdom/build/package/init'
import { h } from 'snabbdom/build/package/h'

const patch = init([])

let vnode = h('div#container', [
    h('h1', 'Hello Snabbdom'),
    h('p', '这是一个p')
])

let app = document.querySelector('#app')
let oldVnode = patch(app, vnode)

// 模拟请求服务更新页面数据
setTimeout(() => {
    vnode = h('div#container', [
        h('h1', 'Hello World'),
        h('p', '这是一个ppppppppppp')
    ])
    patch(oldVnode, vnode)

    // 清除div中的内容 '!'表示创建空的注释节点
    // patch(oldVnode, h('!'))
}, 2000)

浏览器执行结果
2s之后页面内容更新
在这里插入图片描述

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-12 16:30:39  更:2021-08-12 16:32:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 9:27:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码