We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
报告:Vue.js内部当数据变化后,操作的是虚拟DOM,会对比新旧两次虚拟DOM的差异,再把差异更新到真实DOM
虚拟DOM如何工作的?
Virtual DOM虚拟DOM:由普通的JS对象来描述DOM对象,因为不是真实的DOM对象,所以叫Virtual DOM
Virtual DOM
{ sel: 'div', data: {}, children: undefined, text: '1', elm: undefined, key: undefined }
MVVM
模板引擎
diff
描述:
维护视图和状态的关系
复杂视图情况下提升渲染性能
除了渲染DOM以外,还可以实现SSR(Nuxt.js/Next.js)、原生应用(Weex/React Native)、小程序(mpvue/uin-app)等
Nuxt.js/Next.js
Weex/React Native
mpvue/uin-app
Virtual DOM库
parcel
yarn init -y yarn add parcel-bundler
package.json
scripts
"scripts": { "dev": "parcel index.html --open", "build": "parcel build index.html" }
index.html package.json -src main.js
import
yarn add snabbdom
import { h, thunk, init } from 'snabbdom'
Snabbdom核心仅提供最基本的功能,只导出了三个函数init()、h()、thunk()
init()是一个高阶函数,返回patch()
init()
patch()
h()返回虚拟节点VNode,这个函数我们在使用Vuejs的时候见过
h()
new Vue({ router, store, render: h => h(App) }).$mount('#app')
thunk()是一种优化策略,可以在处理不可变数据时使用
thunk()
注意:导入不能使用import snabbdom from 'snabbdom'
import snabbdom from 'snabbdom'
原因:末尾到处使用的语法时export到处API,没有使用export default导出默认输出
export {h} from './h' export {thunk} from './thunk' export function init(modules: Array<Partial<Module>>, domApi?: DOMAPI){ }
//main.js import {h, init} from 'snabbdom' /** * 1.hello world * 参数:数组、模块 * 返回值:patch函数,作用对比两个vnode的差异更新到真实DOM */ let patch = init([]) /** * 第一个参数:标签+选择器 * 第二个参数:如果是字符串的话就是标签中内容 */ let vnode = h('div#container.cls', 'hello world') let app = document.querySelector('#app') /** * 第一个参数:可以是DOM元素,内部会把DOM元素转换为VNode * 第二个参数:VNode * 返回值:VNode */ let oldVnode = patch(app, vnode) //假设的时刻:覆盖之前的元素 vnode = h('div', 'hello snabbdom') patch(oldVnode, vnode)
import { h, init } from 'snabbdom' let patch = init([]) let vnode = h('div#contatainer', [ h('h1', 'hello'), h('p', 'p标签') ]) let app = document.querySelector('#app') let oldVnode = patch(app, vnode) setTimeout(() => { vnode = h('div#contatainer', [ h('h1', '22222'), h('p', '11111') ]) patch(oldVnode, vnode) //清空页面元素-错误:无法读取null的key属性 //patch(oldVnode, null) patch(oldVnode, h('!')) },2000)
<script src="./src/main.js"></script> <!--要引入-->
setAttribute()
attributes
element[attr] = value
sel
data-*
delayed/remove/destroy
//main.js import { init, h } from 'snabbdom' // 1.导入需要的模块 import style from 'snabbdom/modules/style' import eventlisteners from 'snabbdom/modules/eventlisteners' // 2.init()中注册模块 let patch = init([ style, eventlisteners ]) // 3.使用h()函数的第二个参数传入模块需要的数据(对象) /**以前的h() * let vnode = h('div#contatainer', [ * h('h1', 'hello'), * h('p', 'p标签') * ]) */ let vnode = h('div', { style: { backgroundColor: 'red' }, on: { click: eventHandler } },[ h('h1','hello!'), h('p','这是p') ]) function eventHandler() { console.log('1') } let app = document.quertSelector('#app') patch(app, vnode)
Vue中的h()函数支持组件机制,但Snabbdom不支持,但一样可以传入选择器
hyperscript
函数重载
可以定义两个重名函数,通过参数个数、类型不同来区分
分析:h.ts中重载的几个h()函数
h.ts
export interface VNode { //选择器 sel: string | undefined; //节点数据:属性/样式/事件 data: VNodeData | undefined; //子节点:和text只能互斥 children: Array<VNode | string> | undefined; //记录vnode对应的真实DOM elm: Node | undefined; //节点中的内容,和children只能互斥 text: string | undefined; //优化用 key: Key | undefined; }
patchVnode()
removeVnodes()
setTextContent()
updateChildren()
The text was updated successfully, but these errors were encountered:
No branches or pull requests
报告:Vue.js内部当数据变化后,操作的是虚拟DOM,会对比新旧两次虚拟DOM的差异,再把差异更新到真实DOM
虚拟DOM库Snabbdom源码解析
Virtual DOM
虚拟DOM:由普通的JS对象来描述DOM对象,因为不是真实的DOM对象,所以叫Virtual DOM为什么使用?
MVVM
框架,解决了视图和状态的同步问题模板引擎
简化视图,但是它没有解决跟踪状态变化问题,于是出现了Virtual DOMVirtual DOM
好处是当状态改变不需要立即更新DOM,创建一个虚拟树来描述DOM,Virtual DOM内部将弄清楚如何有效(diff
)的更新DOM描述:
作用
维护视图和状态的关系
复杂视图情况下提升渲染性能
除了渲染DOM以外,还可以实现SSR(
Nuxt.js/Next.js
)、原生应用(Weex/React Native
)、小程序(mpvue/uin-app
)等Virtual DOM库
创建项目
parcel
parcel
package.json
的scripts
导入Snabbdom
import
Snabbdom核心仅提供最基本的功能,只导出了三个函数init()、h()、thunk()
init()
是一个高阶函数,返回patch()
h()
返回虚拟节点VNode,这个函数我们在使用Vuejs的时候见过thunk()
是一种优化策略,可以在处理不可变数据时使用注意:导入不能使用
import snabbdom from 'snabbdom'
原因:末尾到处使用的语法时export到处API,没有使用export default导出默认输出
Snabbdom代码演示
模块
setAttribute()
attributes
模块相似,设置DOM元素的属性element[attr] = value
sel
选择器data-*
的自定义属性delayed/remove/destroy
模块使用
init()
中注册模块h()
函数创建VNode的时候,可以把第二个参数设置为对象,其它参数往后移Snabbdom源码解析
Snabbdom核心
h()
Vue中的h()函数支持组件机制,但Snabbdom不支持,但一样可以传入选择器
hyperscript
,使用JavaScript创建超文本函数重载
可以定义两个重名函数,通过参数个数、类型不同来区分
分析:
h.ts
中重载的几个h()函数VNode
VNode渲染真实DOM
patch(oldVnode, newVnode )
patch()
打补丁,把新节点中变化的内容渲染到真实DOM,最后返回新节点,作为下一次处理的旧节点patchVnode()
:对比新旧节点VNode是否是相同节点removeVnodes()
,重新渲染setTextContent()
直接更新文本内容updateChildren()
:如果新的VNode有children,判断子节点是否有变化,判断子节点的过程使用的就是diff算法init函数
patch函数
The text was updated successfully, but these errors were encountered: