开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情
在vue中我们常用到模板,正是这些模板才让我们能将DOM与动态数据绑定在一起,而不是像原生js那样操作DOM节点去绑定数据。这篇文章我们来介绍一下模板相关的知识,比如编译原理,语法等。
模板
模板其实就是vue里面的View, 也就是视图。可以理解成被vue实际控制的页面片段。在vue中渲染流程其实就是将模板转成虚拟DOM,然后再转成实际DOM的过程,而将模板转成虚拟DOM的过程其实就是我们下面要讲到的模板编译(也称为模板渲染)。
编译原理
模板编译其实就是将模板template转成render函数的过程,而渲染函数每次执行时都会生成新的vNode。模板编译可以用下面的图来表示。
1. 确认模板
对于vue项目来说,我们可以在很多地方写元素,处理一些渲染相关的操作。比如:el, template, render, $mount等。那么如何确认我们的模板内容呢?
1.1 渲染到哪个根节点上?
这个主要是根据el属性来判断,el属性值是什么,那么根节点就是什么。没有el属性的话,那么就会根据$mount挂载时去找根节点,挂载在什么上面,什么就是根节点。
1.2 渲染哪个模板到根节点上?
这个主要取决于render函数,
- 如果有render函数的话,先执行render函数,render函数上渲染的模板优先级比template高。
- 如果没有render函数的话,再去找是否定义了template.
- 定义了template, 将template转成render函数所需要的格式(字符串),然后再执行render函数生成模板
- 没有定义template, 就将根节点的outHtml的内容转成render函数所需要的格式(字符串),然后再执行render函数生成模板。
2. 将模板解析成AST
这个过程主要是通过解析器来完成的,AST其实就是用js对象来描述节点。解析器的原理是一小段一小段地截取模板字符串,每截取一小段字符串,就会根据截取出来的字符串类型触发不同的钩子函数,直到模板字符串截空停止。然后使用栈来确定层级关系。
3. 标记AST中的静态节点
Vue的数据是响应式的,但在模板中并不是所有的都是响应式的。有一些数据首次渲染后就不会再发生变化,比如v-once指定的,或者是一些不变的内容,那么对应的DOM也不会变化。优化就是深度遍历抽象语法树,按照相关条件对树节点进行标记。这些被标记的节点(静态节点)也就是不会发生变化的节点,我们就可以跳过对它们的比对,对运行时的模板起到很大的优化作用。
4. 将AST转化成渲染函数的字符串
这个过程其实就是递归AST生成字符串,先生成根字符串,然后再生成后面的子节点字符串,将子节点字符串拼接在根节点字符串上,层层递进,最后就可以得到一个完整的字符串。
模板语法
在vue中,模板语法主要分为两大类:插值语法和指令语法。
插值语法
插值语法就是我们常用到的{{}},这种语法主要用在标签体里面。
1. mustache语法
这种语法就是我们经常会用到的一种语法,就是将数据变量展示到template模板中。 1.1 基本用法
<div>{{msg}}</div>
data () {
return {
msg: ''
};
},
1.2 js表达式用法
<div>{{num * 2 + 650}}</div>
data () {
return {
num: 4
};
},
1.3 三元运算符
<div>{{num ? 10 : 20}}</div>
data () {
return {
num: 4
};
},
1.4 调用methods方法里面的方法
<div>{{consoleMsg('hello')}}</div>
consoleMsg(msg) {
return msg;
}
2. v-once语法
v-once语法指令元素只渲染一次,后面变量无论发生什么改变,页面都不会发生变化
<div v-once>{{msg}}</div>
data () {
return {
msg: ''
};
},
3. v-text语法
v-text用于更新元素的textContent,我们通常写的模板语法其实就是用来更新这个的
<div>{{msg}}</div>
// 等价于
<div v-text="msg"></div>
4. v-html语法
我们一般在{{}}里面写的或者执行返回的内容都是文本内容,如果想要往模板里面插入html内容,需要借助v-html指令来完成。
<div v-html="<span>html内容</span>"></div>
5. v-pre语法
如果某个元素使用了v-pre,那么当前元素及其子元素在模板编译阶段会被跳过,直接显示mustache标签
<div v-pre></div>
指令语法
除了上面介绍的一些插值模板语法之外,还有一种模板语法就是指令语法。指令语法是作用在标签上的,常常以v-前缀的特殊特性,比如前面看到的v-html、v-once等。Vue指令的特性的值预期是单个JavaScript表达式。Vue指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于DOM。
v-bind
v-bind就是给元素绑定某个属性,其中属性值可以是变量或者常量
<a v-bind:href="url"></a>
// 简写形式
<a :href="url"></a>
v-on
v-on就是给元素绑定事件。
<div class="box3" v-on:click="consoleMsg('left')"></div>
// 简写方式
<div class="box3" @click="consoleMsg('left')"></div>
等等
除了上面介绍的这两种指令之外,vue还有很多其他指令,这些指令最后都能渲染出对应的属性或表现方法。