学习Vue.js中的render函数
最近在研究Vue.js的内容,感觉render函数理解有些吃力,那就写篇笔记记录一下吧。
Vue.js的工作流程
先看一张Vue的工作流程图:
由这张图可以看出:Vue先把现有的template解析成ast(Abstract Syntax Tree - 抽象语法树),再将抽象语法树编译为render函数,然后把render函数加载到一个虚拟的DOM对象中(其实中间还有进行一系列的复杂操作,这里只是简单解释),最后由虚拟DOM渲染到真实的DOM,也就是界面中。
为什么要使用render函数
假设一个原本的Vue实例是这样的:
1 | new Vue({ |
由于在Vue对象有template属性,并且在template中使用的一个叫App的组件,所以Vue会先把template中的App抽象到语法树中,才能知道有App这个组件,从而去寻找App组件的构造器,以及加载到render函数,渲染等步骤。
对于这个例子,Vue的处理流程是这样的:
Template => AST => Render => VirtualDom => DOM
现在我们把template交给render函数处理:
1 | new Vue({ |
把箭头函数的写法改成ES5原生写法:
1 | new Vue({ |
上面的h对象就是这里的createElement,它是一个函数。Vue默认把它叫做h函数,其中 根据 Vue.js 作者 Even You 的回复,h 的含义如下:
It comes from the term “hyperscript”, which is commonly used in many virtual-dom implementations. “Hyperscript” itself stands for “script that generates HTML structures” because HTML is the acronym for “hyper-text markup language”.
它来自单词
hyperscript
,这个单词通常用在 virtual-dom 的实现中。Hyperscript
本身是指生成HTML 结构的 script 脚本
,因为 HTML 是hyper-text markup language
的缩写(超文本标记语言)
这样处理之后,Vue的处理流程就变成了:
Render => VirtualDom => DOM
省去了从Template解析编译到Render的过程,由此以来便节省了内存和依赖。
Vue CLI中render函数的预使用
在使用Vue脚手架创建项目时,会有下面的选择:
Vue build:
- Runtime + Compiler: recommended for most users
- Runtime-only: about 6KB lighter min+gzip, but templates (or any Vue-specific HTML) are ONLY allowed in .vue files - render functions are required elsewhere
在正式的生产环境中,我们一般会选择第二种runtine-only的方式构建项目,这样就不会为项目安装template的编译器,转而要求开发人员使用render函数进行template的加载,虽然增大了开发难度,但却为项目提高了性能。
createElement函数的详细用法
直接创建标签
这里createElement函数接收三个参数:
- 标签名(String):如h2,p,div
- 标签的property(Object):如class属性:{ class: ‘box’ }
- 标签的Content(Array):比如一段文本:[ ‘Some Text’ ]
写出来的例子就是这样的:
1 | new Vue({ |
这就在页面中插入了一个HTML标签:
1 | <h2 class = 'box'> |
嵌套式写法
在原本的内容上再加入一个元素:
1 | new Vue({ |
再原本的h2的标签上再加入了一个按钮:
1 | <h2 class = 'box'> |
传入组件
先创建一个组件对象,然后把组件对象传入改函数:
1 | const cpn = { |
正如最上面提到的写法,我们在使用下面的代码引入App时,App就已经是一个含render函数的对象。
1 | import App from './App.vue' |
至于原因,是因为我们在使用Webpack时用到了一个Loader,叫做vue-template-compiler,正是这个Loader的存在,使得我们在引入vue文件时,它就已经被转换为了一个可以被render函数使用的对象。