vue 源码分析 step_2-初始化过程中的真实 DOM 是如何生成的?

本文探讨Vue的初始化过程中,真实DOM如何通过编译生成的代码字符串及mounted方法来创建。重点关注mountComponent方法和update过程,揭示__patch__方法在生成DOM时调用浏览器API如createElement, createText的细节。" 113319219,10293964,Spring Boot整合MySQL与JPA创建Web应用实战,"['Spring框架', '数据库连接', 'Web开发', 'Java', 'ORM框架']
摘要由CSDN通过智能技术生成

在之前的分析中,我们知道在完全版本的 Vue 中,最终会通过编译生成代码字符串,并且将字符串生成了函数。

...
res.render = createFunction(compiled.render, fnGenErrors)
....

function createFunction (code, errors) {
  try {
    return new Function(code)
  } catch (err) {
    errors.push({ err, code })
    return noop
  }
}

那为什么生成了代码字符串就能有真实 DOM 出呢?可能会想到因为调用了 mounted 方法,那么 mounted 方法内部又是如何生成 DOM 的呢?


找到 monte的实现:

/* @flow */

import Vue from 'core/index'
import { mountComponent } from 'core/instance/lifecycle'
import { inBrowser } from 'core/util/index'

import { patch } from './patch'

// 给全局挂在 patch 方法
// install platform patch function
Vue.prototype.__patch__ = inBrowser ? patch : noop

// public mount method
// 挂在 mount 方法
Vue.prototype.$mount = function (
  el?: string | Element,
  hydrating?: boolean
): Component {
  el = el && inBrowser ? query(el) : undefined
  return mountComponent(this, el, hydrating)
}

export default Vue
  • 给Vue 实例挂载了__patch__方法
  • 挂载了$mount,并且初始化了组件

mountComponent 方法

export function mountComponent (
  vm: Component,
  el: ?Element,
  hydrating?: boolean
): Component {
  vm.$el = el
  if (!vm.$options.render) {
    vm.$options.render = createEmptyVNode
  }
  callHook(vm, 'beforeMount')

  let updateComponent
  /* istanbul ignore if */
  if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
    updateComponent = () => {
      ...
      const vnode = vm._render()
      mark(endTag)
      measure(`vue ${name} render`, startTag, endTag)

      mark(startTag)
      vm._update(vnode, hydrating)
      
    }
  } else {
    updateComponent = () => {
      vm._update(vm._render(), hydrating)
    }
  }

  ...
  return vm
}

都调用了 update方法,而 update 方法,便是__patch__的过程。

Vue.prototype._update = function (vnode: VNode, hydrating?: boolean) {
    vm._vnode = vnode
   ...
    if (!prevVnode) {
      // initial render
      vm.$el = vm.__patch__(vm.$el, vnode, hydrating, false /* removeOnly */)
    } else {
      // updates
      vm.$el = vm.__patch__(prevVnode, vnode)
    }
   ...
  }

patch 的过程会创建元素,底层会调用浏览器的creatElement,creatText 等方法去生成标签。

应该注意,这是一个初始化的过程,并不涉及到 old Vnode,所以是以现有的Vnode 去生成真实 Dom

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值