Anaconda 微信小程序教程 extjs6.5 iic mfc SCI http Jetbains全家桶 multithreading mysqli graphics devise 建筑资质 vue源码下载 vue绑定点击事件 支付网站建设 electron教程 ie内核浏览器怎么设置 ab软启动器 kubernetes实战 kubernetes官网 python库 python连接mysql数据库 python位操作 java包 java中scanner java求和 java自学教程 java抽象方法 java怎么写接口 java时间戳转日期 java删除文件 java泛型方法 java集成开发环境 java接口调用 nginx安装教程 html实例教程 windows7loader hadoop权威指南 笔记本外接显示器好吗
当前位置: 首页 > 学习教程  > 编程语言

学习十六、Vue 中的虚拟 dom

2020/11/4 15:24:30 文章标签:

1、什么是虚拟 DOM - 虚拟 DOM(Virtual DOM)是使用 JavaScript 对象描述真实 DOM - Vue.js 中的虚拟 DOM 借鉴 Snabbdom,并添加了 Vue.js 的特性。 例如: 指令和组件机制 2、 为什么要使用虚拟 DOM - 避免直接操作 DOM,提高开发效率 - 作为一个中间层可以跨平台…

1、什么是虚拟 DOM

- 虚拟 DOM(Virtual DOM)是使用 JavaScript 对象描述真实 DOM

- Vue.js 中的虚拟 DOM 借鉴 Snabbdom,并添加了 Vue.js 的特性。

  例如: 指令和组件机制

 

2、 为什么要使用虚拟 DOM

- 避免直接操作 DOM,提高开发效率

- 作为一个中间层可以跨平台

- 虚拟 DOM 不一定可以提高性能

  - 首次渲染的时候会增加开销

  - 复杂视图情况下提升渲染性能

 

3、Vue 虚拟 dom 完整的渲染过程

  • new Vue()
  • this._init()
  • vm.$mount()
    • src/platforms/web/entry-runtime-with-compiler.js
    • 如果没有传递 render,把模板编译成 render 函数
    • compileToFunction() 生成 render() 渲染函数
    • option.render = render
  • vm.$mount
    • src/platforms/web/runtime/index.js
    • mountComponent()
  • mountComponent(this, el)
    • src/core/instance/lifecycle.js
    • 判断是否含有 render 选项,如果没有但是传入了模板,并且当前是开发环境,会发送警告
    • 触发 beforeMount
    • 定义 updateComponent
      • vm._update(vm._render(), ...)
      • vm._render() 渲染,渲染虚拟DOM
      • vm._update() 更新,将虚拟DOM转移成真实 DOM
    • 创建 Watcher 实例
      • updateComponent 传递
      • 调用 get() 方法
    • 触发 mounted
    • return vm
  • watcher.get()
    • 创建完 watcher 回调用一次 get
    • 调用 updateComponent()
    • 调用 vm._render() 创建 Vnode
      • 调用 render.call(vm._renderProxy, vm.$createElement)
      • 实例化时 Vue 传入的 render()
      • 或者编译 template 生成的 render()
      • 返回 VNode
    • 调用 vm._update(vnode, ...)
      • 调用 vm.patch(vm.$el, vnode) 挂载真实 DOM
      • 记录 vm.$el
  • updateComponent()
  • vm._render()
    • vnode = render.call(vm._renderProxy, vm.$createElement)
    • vm.$createElement()
      • h函数,用户设置的 render 函数中调用
      • createElement(vm, a, b, c, s, true)
    • vm._c()
      • h 函数,模板编译的 render 函数中调用
      • createElement(vm, a, b, c, d, true)
    • _createElement()
      • vnode = new VNode(config.parePlatformTagname(tag), data, children, undefined, undefined, context)
      • vm._render() 结束,返回 VNode
  • vm._update()
    • 负责把虚拟 DOM,渲染成真实 DOM
    • 首次执行 vm.patch(vm.$el, vnode, hydrating, false)
    • 数据更新 vm.patch(prevVnode, vnode)
  • vm.patch()
    • runtime/index.js 中挂载 Vue.prototype.patch
    • runtime/patch.js 的 patch 函数
    • 设置 modules 和 nodeOps
    • 调用 createPacthFunction() 函数 返回 patch 函数
  • patch()
    • vdom/patch.js 中的 createPatchFunction 返回 patch 函数
    • 挂载 cbs 节点的属性/事件/样式操作的钩子函数
    • 判断第一个参数是真实 DOM 还是虚拟 DOM。首次加载,第一个参数就是真实 DOM,转换成 VNode,调用 createElm
    • 如果是数据更新的时候,新旧节点是 sameVnode 执行 patchVnode,就是Diff
    • 删除旧节点
  • createElement(vnode, insrtedVnodeQueue)
    • 把虚拟节点,转换成真实 DOM,并插入到 DOM 树
    • 把虚拟节点的 children,转换为真实 DOM,并插入到 DOM 树
  • patchVnode
    • 对比新旧Vnode,以及新旧VNode的子节点更新差异
    • 如果新旧VNode都有子节点并且子节点不同的话,会调用updateChildren 对比子节点的差异
  • updateChildren
    • 从头和尾开始依次找到相同的子节点进行比较 patchVnode,总共有四种比较方式
    • 在老节点的子节点中查找 newStartVnode,并进行处理
    • 如果新节点比老节点多,把新增的子节点插入到 DOM 中
    • 如果老节点比新节点多,把多余的老节点删除

本文链接: http://www.dtmao.cc/news_show_350381.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?