学习vue源码(10)手写render渲染函数

compile 部分已经讲完了(compile部分分为 解析器 + 优化器+ 代码生成器),终于走到了 render,今天就来给自己记录下渲染三部曲的第二部render,(渲染三部曲= compile + render生成Vnode + 将Vnode通过 update 挂载到 页面上),update里 有一系列 diff操作。咦,render 内容不多的噔噔噔噔render 的作用大家应该清楚就是 执行 compile 生成的 render函数,然后得到返回的 vnode 节点比如现在存在
摘要由CSDN通过智能技术生成


compile 部分已经讲完了

compile部分分为 解析器 + 优化器+ 代码生成器),

终于走到了 render,今天就来给自己记录下渲染三部曲的第二部render,

渲染三部曲= compile + render生成Vnode + 将Vnode通过 update 挂载到 页面上),

update里 有一系列 diff操作。

咦,render 内容不多的

噔噔噔噔

render 的作用大家应该清楚

就是 执行 compile 生成的 render函数,然后得到返回的 vnode 节点

比如现在存在这个简单的模板

经过 compile 之后,解析成了对应的 render 函数,如下

function render() {
       

    with(this) {
           

        return _c('div', {
               

            attrs: {
                   

                "data": 111

            }
        },
        [_v(111)])
    }
}

看着这个莫名其妙的 render 函数,里面都是些什么东西?

不怕,主要是出现了两个函数,我们要探索的就是这两个东西

_c , _v

这个两个函数的作用,都是创建 Vnode,但是创建的过程不一样

并且 render 函数执行的时候,会绑定上 模板对应的实例 为上下文对象

模板是属于哪个实例的,就绑定哪个实例

render.call(实例)
再通过 with 的作用

调用 _c 和 _v 就相当于 vm._c 和 vm._v

什么是 vm._v

现在就来看看 vm._v 是哪里来的

function installRenderHelpers(target) {
   
    target._v = createTextVNode;
}

installRenderHelpers(Vue.prototype);

由上面可知,每个Vue 实例都会继承有 _v 这个方法,所以可以通过 vm._v 直接调用

再来看看 _v 对应的 createTextVNode 的作用是什么

创建文本节点!!

看下源码

function createTextVNode(val) {
       

    return new VNode(        

        undefined, undefined,        

        undefined, String(val)

    )
}

比如这个模板

{ {data}} 虽然是字符串,但是也要作为一个子节点存在,所以就当做是 文本节点

而 data 的值是 111

然后 上面的模板就会得到这样的 Vnode 结构如下

什么是 vm._c

_c 是一个大头,render 的重中之重,先来看看他是怎么来的

function initRender(vm) {
   
    vm._c = function(a, b, c, d) {
           

        return createElement(vm, a, b, c, d);

    };
}

Vue.prototype._init = function(options) {
   
    initRender(this)
}

在实例初始化的时候,就会给实例绑定上 _c 方法

所以,vm 可以直接调用到 _c

看了上面的源码,看到 _c 内部调用了 createElement

那就来看看createElement 的源码吧

个人已经简化得非常简单,觉得不偏离我们的主题就可以

function createElement(
    context, tag, data, children

) {
       

    return _createElement(

        context, tag, data, children
    )
}
function _createElement(

    context, tag, data, children

) {
       



    var vnode;    



    if (如果tag是正常html标签) {
   

        vnode = new VNode(
            tag, data, children,
            undefined, undefined,
            context
        );
    }
    .....如果tag是组件名,就特殊处理 ,处理流程已经省略



    if (Array.isArray(vnode))

        return vnode    

    else {
         

        // ...动态绑定 style ,class,代码已经省略

        return vnode
    }
}

你一看

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值