Vue模板渲染的原理是啥

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue模板渲染的原理是啥相关的知识,希望对你有一定的参考价值。

参考技术A vue中的模板template无法被浏览器解析并渲染,因为这不属于浏览器的标准,不是正确的html语法,所有需要将template转化成一个javascript函数,这样浏览器就可以执行这一个函数并渲染出对应的HTML元素,就可以让视图跑起来了,这一个转化的过程,就成为模板编译。

模板编译又分三个阶段,解析parse,优化optimize,生成generate,最终生成可执行函数render。

parse阶段:使用大量的正则表达式对template字符串进行解析,将标签、指令、属性等转化为抽象语法树AST。
optimize阶段:遍历AST,找到其中的一些静态节点并进行标记,方便在页面重渲染的时候进行diff比较时,直接跳过这一些静态节点,优化runtime的性能。
generate阶段:将最终的AST转化为render函数字符串。

vue中渲染函数Render原理解析

参考技术A render函数的职责就是把模板解析成Vnode(虚拟DOM)节点

可以分解成几个问题:
1.模板编译的输出结果是什么?
模板编译会将用户写的模板↓

转换成用层级对象表达的ast

因为本文的重点不是模板编译,所以这里的转换过程略,但我推荐你
https://vue-js.com/learn-vue/complie/
可以解答你的疑惑。

不用急,函数内容(with(this)....)的形成会在后面讲到。
再说明一点,你可能会奇怪render函数为什么要先

这其实是一种特殊语法,在with内部的函数执行环境会切换为this,_c明明没作为参数传进函数体内部,但为何能调用?因为this上有_c方法,而函数内部环境又是this所以能直接调用,而这个this是什么?实际上就是vue实例vm啦!

中间函数会多次调用_c,也就是createElemnt来生成vnode,
_c的作用是根据用户输入的参数来生成相应的vnode节点,官方api文档中createElement的用法如下,是不是和上面render函数内的内容很像,实际上就是一回事。

PS:vnode长什么样子?如下,这就是render最后执行的结果

前人已经讲得很完备了,直接贴出来
https://vue-js.com/learn-vue/complie/codegen.html#_1-%E5%89%8D%E8%A8%80

在initRender中vue为vue的实例vm定义了_c函数,
这就为渲染函数中要调用的_c埋下了伏笔。
但是这里实际上还不是真正定义render函数的位置,那么真正定义render函数的位置在哪里的?
在render.js文件中,滚轮继续向下翻我们发现了这个↓

观察 vnode = render.call(vm._renderProxy, vm.$createElement)就是调用render函数的地方,并生成了vnode最后返回vnode节点
在此之后,vnode利用diff算法就可以完成对页面的数据更新了。

执行render的过程就是将_c执行,补充_c返回的vnode对象的过程

那么非常感谢你看到这里,那么最后我们再解释一下_c也就是createElement相信你就能完全弄明白整个render的过程了!
以下是createElement的源码:

第一层createElement只是个中间层,它实际上是为了调用_createElement而做了一些中间处理

而对_createElement大致扫过一眼,最后return的是vnode节点,这就是_createElement的作用对比render内部来看:
根据环境(context,一般是vm),标签(tag:div),data: attrs:"id":"NLRX",和 children(子节点)来生成vnode

以上是关于Vue模板渲染的原理是啥的主要内容,如果未能解决你的问题,请参考以下文章

vue渲染虚拟dom树原理

VUE2.0 模板编译原理:解析器

VUE2.0 模板编译原理:解析器

Vue原理-组件渲染/更新过程

Vue渲染原理

vue中,我从后台取出数据渲染vue组件,我数据渲染出来了,但是页面有报错,是啥原因