虚拟DOM之Snabbdom的使用

Snabbdom是一个虚拟DOM库。 

parcel是一个打包工具,使用非常简单,0配置。

创建Snabbdom项目结构的基本步骤:

//创建项目目录
md snabbdom-demo
//进入项目
cd snabbdome-demo
//创建package.json
npm init或yarn init -y
//本地安装parcel-bundler
npm install parcel-bundler或yarn add parcel-bundler
//在package.json文件中,script项配置启动命令和打包命令
"script":{
    "dev":"parcel index.html --open",//如果要浏览器自动打开的话就加上--open
    "build":"parcel build index.html"//index.html是入口文件
}

开始写项目的基本步骤:

//安装snabbdom
npm install snabbdom --save或yarn add snabbdom
//注意新版本似乎有问题,引入以后报错,所以安装的时候可以安装0.7版本的
npm install [email protected]

//引入snabbdom
import {h,thunk,init} from "snabbdom";
//注意snabbdom是使用export导出的,所以没办法不写{},而且看源码,它一共导出了三个方法。
//不过使用requie的方式导入的话,可以写成const snabbdom=require("snabbdom"),至于为什么require可以,具体见ES6和CommonJS模块化的差异

init()是一个高阶函数,返回patch()。

h()返回虚拟节点VNode。(vue的render里面有使用到这个方法哦)

thunk()一种优化策略,可在处理不可变数据时使用。

具体使用:

import { h, thunk, init } from "snabbdom";

//patch方法比较两个vnode的差异并更新到真实dom中,返回值是虚拟dom。第一个参数可以是DOM元素,内部会把DOM元素转换成vnode
const patch=init([]);

let vnode=h("div#box.box","hello");
const app=document.querySelector("#app");
const oldVnode=patch(app,vnode);
//至此,重新运行,页面中的
将会被替换成
hello
console.log(oldVnode) vnode=h("div.box","hello snabbdom"); patch(oldVnode,vnode); //至此,重新运行,页面中的
hello
将会被替换成
hello snabbdom

div中加子元素,h函数的第二个参数将会是一个数组

import {h, thunk,init} from "snabbdom";

const patch=init([]);
const app=document.querySelector("#app");
let vnode=h("div#box",[
    h("h1","我是标题"),
    h("p","我是段落")
]);
const oldVnode=patch(app,vnode);
//两秒钟中内容发生变化
setTime(()=>{
    vnode=h("div#box",[
        h("h1","标题"),
        h("p","段落")
    ]);
    patch(oldVnode,vnode);

    //清空页面元素可以利用注释节点
    patch(oldVnode,h("!"))
},2000)

snabbdom模块的使用:

导入模块,注册模块,使用h函数的第二个参数传入模块需要的数据

import { h, thunk, init } from "snabbdom";
//引入模块
import styles from "snabbdom/modules/style";
import eventlisteners from "snabbdom/modules/eventlisteners";
//注册模块
const patch=init([styles,eventlisteners]);
const app=document.querySelector("#app");
//引入模块时,第二个参数是对象,如果没有子元素,第三个参数就是字符串,有子元素就是数组
let vnode=h("div",{
    style:{
        backgroundColor:"blue"
    },
    on:{
        click:eventHandle
    }
},[
    h("h1","我来测试标题")
]);
function eventHandle(){
    console.log('点击事件')
}
patch(app,vnode);//运行以后页面上就会立马显示出来,感觉#app这个元素有点像一开始用来占位置的

源码解读:

主要是解读h.ts、snabbdom.ts、vnode.ts文件。

了解函数重载的概念。(js里面没有函数重载,ts里面是有的)

h函数核心就是调用vnode返回一个虚拟节点。

vnode:每个vnode都有的属性,sel选择器;data节点数据,属性/样式/事件等;children子节点,与text互斥;elm记录vnode对应的真实DOM;text节点中的内容,与children互斥;key优化用。

snabbdom:vnode如何创建真实节点。

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

你可能感兴趣的:(vue)