一、h()函数简介
h()
函数实现了重载机制,能传多种参数类型。h(tag,data,children)
:
参数一:标签选择器或组件的选项对象
参数二:给标签设置属性或事件
参数三:字符串(内容)/数组(子元素)
使用案例:
const vm = new Vue({
el: '#demo',
render(h) {
const vNode = h('h1', {
attrs: {
id: 'box'}}, this.person)
console.log(vNode)
return vNode
},
data() {
return {
person: 'ls'
}
},
})
这段代码会创建出来一个虚拟DOM
:vNode
,并且会创建对应的真实DOM
,并且填充到el中。
二、虚拟DOM的创建过程
render()
函数接受一个h()
函数作为参数。vm.$createElement()
作为render()
的h()
函数,在创建虚拟DOM
的时候,执行的是vm.$createElement()
。
这里只是进行了一个初始化的定义,真正执行是在初始化渲染的时候,在渲染Watcher
中执行的。参考笔记:初始化渲染的第五章,watcher.get()
中会执行updateComponent()
,在这个函数中,会调用vm._render()
生成虚拟DOM
。vm._update()
生成真实DOM
更新视图。
二、渲染视图
vm._update()
用来更新视图,其内部的关键代码是调用了vm.__patch__()
,这个函数是实现更新视图的关键。vm.__patch__()
的定义如下:
src/platforms/web/runtime/index.ts
Vue.prototype.__patch__ = inBrowser ? patch : noop
判断了一下当前环境,如果是浏览器环境,赋值patch()
,如果是非浏览器环境,值为空函数。那么我们就来看patch()
函数:
src/platforms/web/runtime/patch.ts
export const patch: Function = createPatchFunction({
nodeOps, modules })
createPatchFunction()
函数是一个高阶函数,其内部会返回patch()
函数,来看其内部返回的patch()
函数的执行过程:
updateChildren()
和之前看的SnabbDOM
库的实现大体相同,使用diff算法对比新旧节点的差异。可以参考:
Virtual DOM的实现原理