手写 Vue Router、手写响应式实现、虚拟 DOM 和 D

2022-02-23  本文已影响0人  丽__

Virtual DOM 的实现原理

一、什么是虚拟DOM ----Virtual DOM
二、 为什么要使用Virtual DOM

虚拟DOM用来维护视图和状态的关系

三、虚拟DOM的作用和虚拟DOM库
四、 Snabbdom 的基本使用
//创建项目目录
md snabbdom-demo
//进入项目目录
cd snabbdom-demo 
//创建package.json
npm init -y
//本地安装parcel
npm install parcel-bundler -D

"scripts:"{
  "dev":"parcel index.html --open",
  "build":"parcel build index.html"
}
image.png image.png image.png
//导入snabbdom
 npm install snabbdom@2.1.0


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

const patch = init([])
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')
// patch函数中的第一个参数:旧的VNode,也可以是DOM元素
// 第二个参数:新的VNode
// 返回新的VNode
let oldVnode = patch(app, vnode)

vnode = h('div#container.xxx','hello Snabbdom')
patch(oldVnode,vnode)
image.png
image.png
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', '这是一个段落'),
])

let app = document.querySelector('#app')

let oldVnode = patch(app, vnode)

setTimeout(() => {
  // 更改内容
  //   vnode = h('div#container', [h('h1', 'hello World'), h('p', 'hello P!')])
  //   patch(oldVnode, vnode)

  //清除div中的内容  h('!')-->生成空的节点
  patch(oldVnode, h('!'))
}, 2000)

五、 Snabbdom 模块的使用
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: { background: 'red' } }, 'hello World'),
  h('p', { on: { click: eventHandler } }, 'hello p'),
])

function eventHandler() {
  console.log('点击了')
}

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

六、 Snabbdom 源码解析
npm install
 
npm run build  

查看
七、 h() 函数
//vue中的h函数
new Vue({
  router,
  store,
  render:h => h(App)
}).$mount('#app)
//函数重载--参数个数
function add(a:number,b:number){
  console.log(a+b);
}
function add(a:number,b:number,c:number){
  console.log(a+b+c);
}
add(1,2)
add(1,2,3)
//函数重载--参数类型
function add(a:number,b:number){
  console.log(a+b);
}
function add(a:number,b:string){
  console.log(a+b);
}
add(1,2)
add(1,'2')

// 函数的重载
export function h (sel: string): VNode
export function h (sel: string, data: VNodeData | null): VNode
export function h (sel: string, children: VNodeChildren): VNode
export function h (sel: string, data: VNodeData | null, children: VNodeChildren): VNode
export function h (sel: any, b?: any, c?: any): VNode {
  var data: VNodeData = {}
  var children: any
  var text: any
  var i: number
  // 处理参数,实现重载的机制
  if (c !== undefined) {
    // 处理三个参数的情况
    // sel data children/text
    if (b !== null) {
      data = b
    }
    if (is.array(c)) {
      children = c
      // 如果c是字符串或者数字
    } else if (is.primitive(c)) {
      text = c
      // 如果c 是VNode
    } else if (c && c.sel) {
      children = [c]
    }
  } else if (b !== undefined && b !== null) {
    if (is.array(b)) {
      children = b
    } else if (is.primitive(b)) {
      text = b
    } else if (b && b.sel) {
      children = [b]
    } else { data = b }
  }
  if (children !== undefined) {
    // 处理children中的原始值(string/number)
    for (i = 0; i < children.length; ++i) {
      // 如果child 是string/number,创建文本节点
      if (is.primitive(children[i])) children[i] = vnode(undefined, undefined, undefined, children[i], undefined)
    }
  }
  if (
    sel[0] === 's' && sel[1] === 'v' && sel[2] === 'g' &&
    (sel.length === 3 || sel[3] === '.' || sel[3] === '#')
  ) {
    // 如果是svg,添加命名空间
    addNS(data, children, sel)
  }
  // 返回VNode
  return vnode(sel, data, children, text, undefined)
};

八、 快捷键

快速定位
Alt + ←向左方向键
ctrl+鼠标左键

九、 VNode
image.png
十、 Patch 整体过程分析
十一、patchVnode
image.png
十二、 Diff 算法
image.png
上一篇下一篇

猜你喜欢

热点阅读