编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

Vue源码全面解析三十六 _render函数(生成vnode虚拟DOM结构)

wxchong 2024-12-06 20:13:12 开源技术 23 ℃ 0 评论


我们打开“src/core/instance/render.js”文件,代码如下:

Vue.prototype._render = function (): VNode {
    const vm: Component = this
    const { render, _parentVnode } = vm.$options
    if (_parentVnode) {
      vm.$scopedSlots = normalizeScopedSlots(_parentVnode.data.scopedSlots,vm.$slots, vm.$scopedSlots)
    }
    vm.$vnode = _parentVnode
    // render self
    let vnode
    try {
      currentRenderingInstance = vm
      vnode = render.call(vm._renderProxy, vm.$createElement)
    } catch (e) {
     
     // ...省略部分代码 
      
    } 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()
    }
    vnode.parent = _parentVnode
    return vnode
  }

我们接下来拆分一下该函数的代码:

 const { render, _parentVnode } = vm.$options
 if (_parentVnode) {
   vm.$scopedSlots = normalizeScopedSlots(_parentVnode.data.scopedSlots,vm.$slots, vm.$scopedSlots)
 }
vm.$vnode = _parentVnode

首先是看看是否存在 “_parentVnode” ,如果存在,就调用 “normalizeScopedSlots” 处理 “slot”参数。

vnode = render.call(vm._renderProxy, vm.$createElement)

紧接着调用 render 函数生成 vnode 虚拟节点。render函数代码如下:


最后生成的vnode结构如下:



   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 = c
    }

以上就是生成vnode之后的处理。

1、取出vnode对象的打一个(vnode[0])

2、判断vnode 是否为 Vnode的实例化对象,如果不是将新建一个空的vnode (createEmptyVNode())

 vnode.parent = _parentVnode
return vnode

最后是设置vnode的父级,然后返回vnode。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表