zhuanghaixin / Interview

8 stars 0 forks source link

[vue] Virutal DOM 虚拟DOM? #124

Open zhuanghaixin opened 3 years ago

zhuanghaixin commented 3 years ago

Virtual DOM 概述

什么是虚拟DOM

是由普通的js对象来描述DOM对象,因为不是真实的DOM对象,所以叫Virtual DOM

let element=document.querySelector('#app')
let s=''
for(var key in element){
s+=key+','
}
console.log(s)

image 这个例子可以看出来,我们创建DOM对象的成本是非常高的

为什么使用虚拟DOM

  • 手动操作DOM比较麻烦,还需要考虑浏览器兼容问题,虽然jQuery等库简化DOM操作,但是随着项目复杂性提高,DOM操作变得复杂,既要考虑操作DOM,又要考虑操作数据
  • 为了简化DOM的复杂操作,出现了各种MVVM框架,MVVM #118 框架解决了视图和状态的同步问题 (当数据发生变化自动更新换代视图,当视图发生变化,自动更新数据)

虚拟DOM库——Snabbdom

zhuanghaixin commented 3 years ago

Snanndom基本使用

创建项目

console.log('init') console.log(init) console.log('h') console.log(h) console.log('thunk') console.log(thunk)

## 第一个例子  输出hello world

import {h,init} from 'snabbdom'

// 1. 输出hello world // 返回值 patch函数 作用对比两个vnode的差异更新到真实DOM let patch=init([])

let vNode=h('div#container.cls','Hello World') // 将来要替换app里面到内容 let app=document.querySelector('#app') // patch函数, 第一个参数可以是DOM,内部会把DOM元素转换为VNode // 第二个参数 VNode // 返回值 VNode let oldVNode =patch(app,vNode)

![image](https://user-images.githubusercontent.com/24459069/103759096-1f6f6f80-504e-11eb-8bee-5186f087121e.png)

## 在某个时刻,从服务器中获取数据,并且把新的数据重新赋值给页面中的div
```js
import {h,init} from 'snabbdom'

// 1. 输出hello world
// 返回值 patch函数 作用对比两个vnode的差异更新到真实DOM
let patch=init([])

let vNode=h('div#container.cls','Hello World')
// 将来要替换app里面到内容
let app=document.querySelector('#app')
// patch函数, 第一个参数可以是DOM,内部会把DOM元素转换为VNode
// 第二个参数 VNode
// 返回值 VNode
let oldVNode =patch(app,vNode)

// 在某个时刻,从服务器中获取数据,并且把新的数据Hello Snabbdom重新赋值给页面中的div
vNode=h('div','Hello Snabbdom')
patch(oldVNode,vNode)

image

第二个例子, 在页面中的div放置子元素h1,p

import {h,init} from 'snabbdom'

// 1.  在页面中的div放置子元素h1,p
// 返回值 patch函数 作用对比两个vnode的差异更新到真实DOM
let patch=init([])

let vNode=h('div#container',[
    h('h1','Hello Snabbdom'),
    h('p','这是一个P标签')
])
// 将来要替换app里面到内容
let app=document.querySelector('#app')
// patch函数, 第一个参数可以是DOM,内部会把DOM元素转换为VNode
// 第二个参数 VNode
// 返回值 VNode
let oldVNode =patch(app,vNode)

// // 在某个时刻,从服务器中获取数据,两秒钟后,h1,p替换,重新赋值给页面中的div
setTimeout(()=>{
    console.log(1)
    vNode=h('div#contaiiner',[
        h('h1','Hello world'),
        h('p','Hello p')
    ])
    // 1. 更新DOM
    // patch(oldVNode,vNode)
    // 2. 清空DOM 用注释标签代替
    patch(oldVNode,h('!'))
},2000)
zhuanghaixin commented 3 years ago

Snabbdom 模块使用

常用模块

// 3 使用h()函数的第二个参数传入模块需要的数据(对象) let vNode = h('button', { style: { backgroundColor: 'red' }, on: { click: eventHandler } }, [ h('button','按钮+1') ]) let num=0 function eventHandler() { console.log( '当前数字', num++

)

}

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

let oldVNode = patch(app, vNode)

zhuanghaixin commented 3 years ago

Snabbdom 源码分析

Snabbdom 核心