深入理解Vue源码系列-5.render闪亮登场

422 阅读1分钟

开始

上面写到updateComponent ,他的参数是 vm._update(vm._render(), hydrating),render就在这里。 render怎么搞呢?

去src/core/instance/render.js看看

Vue.prototype._render = function (): VNode {
    const vm: Component = this
    //拿到render
    const { render, _parentVnode } = vm.$options
    
    if (_parentVnode) {
      vm.$scopedSlots = normalizeScopedSlots(
        _parentVnode.data.scopedSlots,
        vm.$slots,
        vm.$scopedSlots
      )
    }

    vm.$vnode = _parentVnode
   
    let vnode
    try {
      
      currentRenderingInstance = vm
        
      //render 这里用代理(开发环境中) 去调用,返回一个vnode  
      // vm.$createElement是在这个文件上面有个initRender 这个方法定义的
      //而这个方法,也是会在上面讲的_init()里有个initRender函数调用的
        //createElement 会返回一个 vnode,vnode之后讲,这里只需要知道render是在这调用的即可
        
        
      vnode = render.call(vm._renderProxy, vm.$createElement)
    } catch (e) {
      handleError(e, vm, `render`)
     
      if (process.env.NODE_ENV !== 'production' && vm.$options.renderError) {
        try {
          vnode = vm.$options.renderError.call(vm._renderProxy, vm.$createElement, e)
        } catch (e) {
          handleError(e, vm, `renderError`)
          vnode = vm._vnode
        }
      } else {
        vnode = vm._vnode
      }
    } finally {
      currentRenderingInstance = null
    }
   
    if (Array.isArray(vnode) && vnode.length === 1) {
      vnode = vnode[0]
    }

    if (!(vnode instanceof VNode)) {
      if (process.env.NODE_ENV !== 'production' && Array.isArray(vnode)) {
        warn(
          'Multiple root nodes returned from render function. Render function ' +
          'should return a single root node.',
          vm
        )
      }
      vnode = createEmptyVNode()
    }
    // set parent
    vnode.parent = _parentVnode
    return vnode
  }
 vnode = render.call(vm._renderProxy, vm.$createElement)

我们先看到 vnode = render.call(vm._renderProxy, vm.$createElement) 这里,就是会调用render函数,call的第一个参数是vm的代理,相当于this把,我们回到new Vue()看看render函数,这里就render函数

new Vue({
  el: '#app',
  router,
  render:h=>h(App),
})

总结

这里我们只要知道render是怎么调用的即可。