Vue源码分析之-虚拟DOM

本文深入探讨了Vue.js中的虚拟DOM概念,包括它的作用、创建过程和VNode结构。通过分析Vue实例的初始化、$createElement函数、VNode的创建及patch函数的执行流程,阐述了虚拟DOM如何提高DOM操作效率并减少性能开销。同时,文章指出设置key属性对于节点重用和减少重绘的重要性。
摘要由CSDN通过智能技术生成

什么是虚拟DOM

  • 虚拟DOM(Virtual DOM)是使用JavaScript对象描述真实DOM!
  • Vue.js中的虚拟DOM借鉴Snabbdom,并添加了Vue.js的特性。
    • 例如: 指令和组件机制

为什么要使用虚拟DOM

  • 避免直接操作DOM,提高开发效率
  • 作为一个中间层可以跨平台
  • 虚拟DOM不一定能够提高性能
    • 首次渲染的时候会增加开销
    • 复杂视图的情况下(如中大型的单页应用SPA)提升渲染性能
      • 如果有频繁DOM操作的话,虚拟DOM在更新真实DOM之前,首先会通过diff算法,对比新旧两个虚拟DOM树对象的差异,最终把差异更新到真实DOM;而不会每次都操作真实DOM。
      • 另外通过给节点设置key属性,可以让节点最大程度得到重用,避免大量的重绘。

虚拟DOM 代码演示

new Vue()实例时,render的定义中有个习惯命名为h的函数类型参数,参数h()函数实际上对应我们源码中的$createElement()。

h() 函数的作用是用来创建一个虚拟节点VNode,调用 h(tag, data, children) 函数的时候需要传入三(4)个参数:

  • tag:标签的名称:string类型 或者 组件的选项对象;
  • data:是用来描述tag的,如果tag是标签,data中可以设置标签的属性或者它定义的DOM的元素属性等等,还可以注册事件。
  • children:可以是字符串或者是数组,
    • 如果是字符串的话,是设置的tag标签里面的内容textContent;
    • 如果是数组的话,是设置tag标签中的子节点,子节点也是vnode类型的。

这里的 h函数 跟 snabbdom中的有些类似,核心作用都是一样的,都是为了创建vnode。 只不过Vue中的 h函数 它里面支持组件 component,并且还支持 slots 插槽。

使用示例:

data: { msg: 'Hello World' },
render(h) {
// h(tag, data, children)
// return h('h1', this.msg)
// return h('h1', { domProps: { innerHTML: this.msg }})
// return h('h1', { attrs: { id: 'title' }}, this.msg)
const vnode = h('h1', { attrs: { id: 'title' }}, this.msg)
console.log(vnode)
return vnode
}

打印的VNode实例

VNode {
asyncFactory: undefined
asyncMeta: undefined
children: [VNode]
componentInstance: undefined
componentOptions: undefined
context: Vue {_uid: 1, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue, …}
data: {attrs: {…}}
elm: h1#title
fnContext: undefined
fnOptions: undefined
fnScopeId: undefined
isAsyncPlaceholder: false
isCloned: false
isComment: false
isOnce: false
isRootInsert: true
isStatic: false
key: undefined
ns: undefined
parent: undefined
raw: false
tag: "h1"
text: undefined
child: undefined
[[Prototype]]: Object
}

VNode相较于真实DOM还是少相当多内容的。

h1#title
__vue__: Vue {_uid: 1, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue, …}
accessKey: ""
align: ""
ariaAtomic: null
ariaAutoComplete: null
ariaBusy: null
ariaChecked: null
ariaColCount: null
ariaColIndex: null
ariaColSpan: null
ariaCurrent: null
ariaDescription: null
ariaDisabled: null
ariaExpanded: null
ariaHasPopup: null
ariaHidden: null
ariaInvalid: null
ariaKeyShortcuts: null
ariaLabel: null
ariaLevel: null
ariaLive: null
ariaModal: null
ariaMultiLine: null
ariaMultiSelectable: null
ariaOrientation: null
ariaPlaceholder: null
ariaPosInSet: null
ariaPressed: null
ariaReadOnly: null
ariaRelevant: null
ariaRequired: null
ariaRoleDescription: null
ariaRowCount: null
ariaRowIndex: null
ariaRowSpan: null
ariaSelected: null
ariaSetSize: null
ariaSort: null
ariaValueMax: null
ariaValueMin: null
ariaValueNow: null
ariaValueText: null
assignedSlot: null
attributeStyleMap: StylePropertyMap {size: 0}
attributes: NamedNodeMap {0: id, id: id, length: 1}
autocapitalize: ""
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值