vue怎么执行回调函数 (vue前端eval函数)

vue源码分析谁比较厉害,vue源码逐行解析

首先我们打开src/core/instance/render.js'文件,代码如下:

export function initRender (vm: Component) {
  vm._vnode = null // the root of the child tree
  vm._staticTrees = null // v-once cached trees
  const options = vm.$options
  const parentVnode = vm.$vnode = options._parentVnode // the placeholder node in parent tree
  const renderContext = parentVnode && parentVnode.context
  vm.$slots = resolveSlots(options.resolveSlots, renderContext)
  vm.$scopedSlots = emptyObject

  vm._c = (a, b, c, d) => createElement(vm, a, b, c, d, false)

  vm.$createElement = (a, b, c, d) => createElement(vm, a, b, c, d, true)

  const parentData = parentVnode && parentVnode.data

  /* istanbul ignore else */
  if (process.env.NODE_ENV !== 'production') {
    defineReactive(vm, '$attrs', parentData && parentData.attrs || emptyObject, () => {
      !isUpdatingChildComponent && warn(`$attrs is readonly.`, vm)
    }, true)
    defineReactive(vm, '$listeners', options._parentListeners || emptyObject, () => {
      !isUpdatingChildComponent && warn(`$listeners is readonly.`, vm)
    }, true)
  } else {
    defineReactive(vm, '$attrs', parentData && parentData.attrs || emptyObject, null, true)
    defineReactive(vm, '$listeners', options._parentListeners || emptyObject, null, true)
  }
}

这个函数的主要功能是:

1、获取_parentVnode对象(子组件存在)

2、将vnode解析为slot对象

3、挂载 '_c'函数(生成vnode)

4、调用defineReactive函数拦截实例的 '$attrs' 和 '$listeners' 属性的操作

 const parentVnode = vm.$vnode = options._parentVnode
  const renderContext = parentVnode && parentVnode.context
  vm.$slots = resolveSlots(options._renderChildren, renderContext)

获取父级 'Vnode' 节点,把 '_renderChildren' 子级的vnode转换为slot插槽(resolveSlots)函数。

 vm._c = (a, b, c, d) => createElement(vm, a, b, c, d, false)

  vm.$createElement = (a, b, c, d) => createElement(vm, a, b, c, d, true)

在实例对象 'vm' 上挂载 ‘_c’ 函数,此函数主要是生成vnode虚拟节点。

关于createElement函数的具体分析,我们留到后面章节。

 defineReactive(vm, '$attrs', parentData && parentData.attrs || emptyObject, null, true)
 defineReactive(vm, '$listeners', options._parentListeners || emptyObject, null, true)

最后拦截对 '$attrs' 和 '$listeners' 属性的操作, '$attrs' 和 '$listeners'都是只读的。

关于defineReactive函数的具体分析,我们留到后面章节。