Virtual DOM 的实现原理(一)----Snabbdom函数

为什么要使用Virtual DOM

1、前端开发刀耕火种的时代

2、MVVM框架解决视图和状态同步问题

3、模板引擎可以简化视图操作,没办法跟踪状态

4、虚拟DOM跟踪状态变化

5、参考github上virtual-dom的动机描述

(1)虚拟DOM可以维护程序的状态,跟踪上一次的状态

(2)通过比较前后两次状态差异更新真实DOM

虚拟DOM的作用

1、维护视图和状态的关系

2、复杂视图情况下提升渲染性能

3、跨平台

(1)浏览器平台渲染DOM

(2)服务端渲染SSR(Nuxt.js/Next.js)

(3)原生应用(Weex/React Native)

(4)小程序(mpvue/uni-app)

虚拟DOM开源库

1、Snabbdom

(1)Vue.js 2.x内部使用的虚拟DOM就是改造的Snabbdom

(2)大约200SLOC(single line of code)

(3)通过模块可扩展

(4)源码使用TypeScripe开发

(5)最快的Virtual DOM之一

2、virtual-dom

Snabbdom的基本使用

1、步骤

(1)安装 parcel,使用简单

Virtual DOM 的实现原理(一)----Snabbdom函数

 

(2)配置 scripts

Virtual DOM 的实现原理(一)----Snabbdom函数

 

 (3)目录结构

Virtual DOM 的实现原理(一)----Snabbdom函数

 Snabbdom基本使用

1、案例一

import { init } from 'snabbdom/build/package/init';
import { h } from 'snabbdom/build/package/h';
const patch = init([])
//第一个参数:标签+选择器
//第二个参数:如果是字符串就是标签中的文本内容
let vnode = h('div#container.cls','Hello World')
let app = document.querySelector('#app')
// 第一个参数:旧的VNode,可以是DOM元素
// 第二个参数:新的VNode
// 返回新的VNode
let oldVnode = patch(app,vnode)
vnode = h('div#container.snabbdom','Hello snabbdom')

patch(oldVnode,vnode)

执行

npm run dev

案例二

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 h1'),
    //     h('p','hello p')
    // ])
    // patch(oldVnode,vnode);
    //清除div中的内容
    patch(oldVnode,h('!'));
}, 2000);

模块的使用

1、官方提供的模板

attributes

props

dataset

class

style

eventlisteners

2、模块的使用步骤

(1)导入需要的模块

(2)init()中注册模块

(3)h()函数的第二个参数处使用模块

3、案例

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、注册模块
const patch = init([
    styleModule,
    eventListenersModule
])
//3、使用h()函数的第二个参数传入模块中使用的数据(对象)
let vnode = h('div',[
    h('h1',{style:{backgroundColor:'red'}},'Hello World'),
    h('p',{ on: { click: eventHandler } },'Hello p')
])
function eventHandler(){
    console.log('干嘛')
}
let app = document.querySelector('#app');
patch(app,vnode);

Snabbdom源码解析概述

1、Snabbdom的核心

(1)Init()设置模块,创建patch()函数

(2)使用h()函数创建JavaScript对象(VNode)描述真实DOM

(3)patch()比较新旧两个Vnode

(4)把变化的内容更新到真实的DOM树

h函数介绍

作用:创建VNode对象

Virtual DOM 的实现原理(一)----Snabbdom函数

 

 Vue中的h函数

Virtual DOM 的实现原理(一)----Snabbdom函数

 

 1、函数重载

(1)参数个数或参数类型不同的函数

(2)JavaScript中没有重载的概念

(3)TypeScript中有重载,不过重载的实现还是通过代码调整参数的

patch整体过程分析

(1)patch(oldVnode newVnode)

(2)把新节点中变化的内容渲染到真实DOM,最后返回新节点作为下一次处理的旧节点

(3)对比新旧VNode是否相同节点(节点的key和sel相同)

(4)如果不是相同节点,删除之前的内容,重新渲染

(5)如果是相同节点,再判断新的VNode是否有text,如果有并且和oldVnode的text不同,直接更新文本内容

(6)如果新的VNode有children,判断子节点是否有变化

 

 

上一篇:常见的http请求方法


下一篇:diff算法