上一章节我们探讨了vue的入门,对vue有了初步的了解,并且掌握了模板语法。本节课我们的学习目标是vue的指令。
首先解释以下什么叫做指令,指定就是命令的意思,人们用指令表达自己的意图。vue中有多种指令,每种指令有不同的功能,比如有个指令的名字叫做v-text,此指令用于主要用来更新html标签InnerText内容,等同于JS操作dom元素的text属性。
除以以外vue还提供了多种指令,接下来我们就开始详细介绍这些指令的使用场景已经使用方式。
2.1 什么是指令
我们已经了解到Vue虽然使用场景与功能类似于JQuery,但是语法习惯完全不同于JQuery,比如Vue使用步骤主要有实例化Vue对象,挂载点使用模板语法绑定数据。除此以外vue指令也是vue使用中的重要组成部分,根据不同的指令有不同的功能,比如绑定事件,渲染InnerText数据,渲染InnerHtml数据。
2.1.1 什么是Vue指令
vue中的指令存在的形式是以v-为前缀的特殊html标签属性,出现在html的标签的属性部分,功能是当表达式的值改变时, 将其产生的连带影响,响应式地作用于 DOM。
Vue指令的组成部分如图2.1所示。
图2.1 指令语法
2.1.2 DOM节点
无论是传统的原生js,还是老牌前端框架JQuery,包括正在学习的Vue,他们的功能主要都是操作dom节点对象,我们这里再复习一下dom节点的相关概念,因为vue指令就是对dom节点的操作。在 HTML DOM 中 , 每一个元素都是节点,vue指令就是节点的特殊属性。Vue.js是数据驱动的,无需手动操作DOM,它通过指令语法,将DOM和数据绑定起来。一旦创建了绑定,DOM将和数据保持同步,每当变更了数据,DOM也会相应地更新。
2.2 指令一览
Vue提供了多种内置的指令,不同的指令有不同的功能,在具体学习每种指令之前,我们先将部分常见指令以表格形式进行一览,如图2.2所示。
图2.2 部分指令一览
2.3 v-if & v-else-if & v-else指令
先描述一个场景:现有一组标签,此标签展示内容只有在当前用户符合某些条件的情况下才显示。
这种类型的功能在开发中是十分常见的,实现思路也很简单,需要先进行判断是否符合条件,根据判断结果来决定是否展示标签。在vue中想要实现此种功能,就需要使用v-if指令。
2.3.1 v-if指令
我们使用v-if指令来实现刚才描述的场景,创建index.html文件,并使用上一章节中我们学习过的内容快速安装vue环境,这里就不在重新阐述。index.html中判断当前level的值是否大于等于10,如果大于10在页面中显示文字:“欢迎来自艾欧尼亚的最强王者上机!”如果levle的值小于10则什么都不显示。为了实现此效果,我们需要使用到v-if指令。index.html代码内容如2-1所示:
例2-1 index.html
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <script src="../vue.js"></script>
- <title>Document</title>
- </head>
- <body>
- <div id="app">
- <!--span只有在levle的值大于等于10的时候才显示-->
- <span v-if="levle>=10">欢迎来自艾欧尼亚的最强王者上机!</span>
- </div>
- <script>
- new Vue({
- el:"#app",
- data:{
- levle: 10
- }
- })
- </script>
- </body>
- </html>
运行效果:
- 当data中的levle的值大于等于10的时候,访问页面在浏览器窗口显示文字“欢迎来自艾欧尼亚的最强王者上机!”。
- 当data中的levle的值小于10的时候,访问页面在浏览器窗口不显示文字。
代码解释:
v-if指令会首先执行表达式,也就是“levle>=10”,表达式得到一个布尔值的结果,如果布尔值为tur则显示v-if指令所在的标签,如果布尔值为false则不显示v-if指令所在的标签元素,值得注意的是并且将v-if指令所在的标签从HTML的document文档对象中移除,表达式判断结果为false时dom文档结构如图2.3所示。
图2.3 v-if表达式判断为false
2.3.2 v-else-if & v-else指令
有过一定编程语言基础的读者肯定了解,选择结构除了有if以外,还有if-else和if -elseif-else结构。v-if可以实现if的选择结构,如果想要实现另外两种结构在vue中需要使用v-else-if和v-else指令。
需求:根据学生成绩score在页面显示ABCD中的某个等级,如果score>=90,显示A;如果90>score>=80,显示B;如果80>score>=60,显示C;如果60<score,显示D。
那么接下来我们创建并编辑index2.html文件,来模拟此功能,index2.html内容如例2-2所示:
例2-2 index2.html
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <script src="./vue.js"></script>
- <title>Document</title>
- </head>
- <body>
- <div id="app">
- 你的成绩为:{{score}}<br/>
- 你的等级为:
- <span v-if="score>=90 && score <=100">A</span>
- <span v-else-if="90 > score && score >= 80">B</span>
- <span v-else-if="80 > score && score >= 60">C</span>
- <span v-else-if="60 > score">D</span>
- <span v-else>score不规范</span>
- </div>
- <script>
- new Vue({
- el:"#app",
- data:{
- score: 61
- }
- })
- </script>
- </body>
- </html>
运行效果:
- 当data中的score的值大于等于90并且小于等于100的时候,访问页面在浏览器窗口显示文字“你的等级为A”。
- 当data中的score的值大于等于80并且小于90的时候,访问页面在浏览器窗口显示文字“你的等级为B”。
- 当data中的score的值大于等于60并且小于80的时候,访问页面在浏览器窗口显示文字“你的等级为C”。
- 当data中的score的值小于于等于60的时候,访问页面在浏览器窗口显示文字“你的等级为D”。
- 当data中的score为其他数值,访问页面在浏览器窗口显示文字“score不规范”。
代码解释:
vue中提供了v-if,v-else-if以及v-else指令实现了选择结构中的多选一场景,这里与其他语言的选择结构思想是类似的这里不再详细描述,注意案例中的代码写法。
2.4 v-show指令
针对于判断条件决定是否显示某个标签的需求我们除了可以使用v-if指令以外,vue还提供了v-show指令,“show”就是显示的意思,此指令根据条件判断决定是否显示所在的标签。此指令的本质是控制切换一个元素的显示和隐藏display属性控制。
接下来我们创建index3.html文件,使用v-show完成与例子2-1i,也就是index.html的效果。
index3.html代码内容如2-3所示:
例2-3 index3.html
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <script src="../vue.js"></script>
- <title>Document</title>
- </head>
- <body>
- <div id="app">
- <!--span只有在levle的值大于等于10的时候才显示-->
- <span v-show="levle>=10">欢迎来自艾欧尼亚的最强王者上机!</span>
- </div>
- <script>
- new Vue({
- el:"#app",
- data:{
- levle: 10
- }
- })
- </script>
- </body>
- </html>
运行效果:
- 当data中的levle的值大于等于10的时候,访问页面在浏览器窗口显示文字“欢迎来自艾欧尼亚的最强王者上机!”。
- 当data中的levle的值小于10的时候,访问页面在浏览器窗口不显示文字。
代码解释:
我们发现从页面的展示效果来说v-show和v-if的功能是一样的,都能够实现表达式得到的布尔值的不同来决定是否显示标签,那么他们的区别是什么?v-show是通过改变标签的css中的display属性来控制显隐,并不像v-if将标签从dom文档对象中移除。我们通过查看页面的文档结构来查看他们的区别,如图2.4所示。
图2.4 v-show表达式判断为false
2.5 v-for指令
对于页面展示中最常见的模块应该是列表或者表格,使用html中的<ul>,<ol>,<li>等标签,列表展示对应的数据格式一般都是数组,数组的条目数一般都是不确定的,我们如何将类型为数组的数据进行循环展示在列表中呢?vue提供了v-for指令,v-for 可以绑定数据到数组来渲染一个列表中。
2.5.1 v-for指令基本使用
需求:data中提供一个数组,属性名为stus,保存了多个学生对象,对象中包含name属性保存学生的名字,使用vue完成将数组的数据循环渲染在列表中。创建index4.html文件,演示v-for指令的使用。index4.html代码内容如2-4所示:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <script src="../vue.js"></script>
- <title>Document</title>
- </head>
- <body>
- <div id="app">
- <ol>
- <li v-for="stu in stus">
- {{ stu.name }}
- </li>
- </ol>
- </div>
- <script>
- new Vue({
- el:"#app",
- data:{
- stus: [
- { name: 'aaa1' },
- { name: 'aaa2' },
- { name: 'aaa3' }
- ]
- }
- })
- </script>
- </body>
- </html>
运行效果如图2.5所示:
图2.5 index4.html运行效果
html的dom文档结构如图2.6所示:
图2.6 index4.html文档结构
代码解释:
v-for指令中的语法为:“item in arr”,从数组arr中取出每一个item,将v-for指令所在的标签循环生成,并且通过标签内部中的模板语法渲染数据。
2.5.2 key属性
vue官方文档中要求我们现在在使用v-for的时候,必须会加上一个必要的key属性。如图2.7所示:
图2.7 官方对key的要求
那么v-for中的键值key到底有什么作用呢?本小节中我们学习key属性。先看key的基本使用,创建index5.html文件,演示key属性的使用。index5.html代码内容如2-5所示:
例2-5 index5.html
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <script src="./vue.js"></script>
- <title>Document</title>
- </head>
- <body>
- <div id="app">
- <ol>
- <li v-for="(stu,id) in stus" :key="id">
- {{ stu.name }}
- </li>
- </ol>
- </div>
- <script>
- new Vue({
- el:"#app",
- data:{
- stus: [
- { name: 'aaa1' ,id:1},
- { name: 'aaa2' ,id:2},
- { name: 'aaa3' ,id:3}
- ]
- }
- })
- </script>
- </body>
- </html>
代码解释:
先描述一下以上代码的运行效果,index5.html展示效果与index4.html一致。key属性配合v-for指令使用的基本语法为:
<elment v-for=”(item,index) in arr” :key=”index”></elment>
其中item为自定义的名字,保存数组中的每一项,index为数组中每一个对象元素中的具有唯一性的属性的属性名。在用v-for更新已渲染的元素列表的时候,会使用就地复用的策略;这就是说列表数据修改的时候,他会根据key值去判断某个值是否修改,如果修改了就重新渲染,不然就复用之前的元素。总结来说,就是通过key值来提升渲染的效率。
2.6 v-text & v-html指令
在原生js中可以操作documen对象的innerText和innerHTML属性,都是操作document对象文本内容,区别在于从innerText操作的是起始位置到终止位置的内容, 但它去除Html标签。innerHTML操作的是从对象的起始位置到终止位置的全部内容,包括Html标签。对在vue中提供了两个指令,分别对应着操作innerText和innerHTML,他们分别是v-text以及v-html。
2.6.1 v-text指令
v-text主要用来更新textContent,可以等同于JS的text属性。
<span v-text="msg"></span>
这两者等价:
<span>{{msg}}</span>
2.6.2 v-html指令
双大括号的方式会将数据解释为纯文本,而非HTML。为了输出真正的HTML,可以用v-html指令。它等同于JS的innerHtml属性。
<div v-html="rawHtml"></div>
这个div的内容将会替换成属性值rawHtml,直接作为HTML进行渲染。
2.7 v-on指令
vue中对dom对象的事件绑定的语法与原生js也不尽相同,本小节我们探讨在vue中如何进行事件的绑定。vue中使用v-on指令用来监听dom事件,以便执行一些代码块。指令的属性值是一个表达式,表达式可以是一个方法名,表示事件触发时执行的方法。
比如对一个button标签绑定一个点击事件:
<button v-on:click="consoleLog"></button>
一般来说我们会使用“@”符号作为v-on的简写,以上代码一般简写为:
<button @click="consoleLog"></button>
此代码表示,按钮在点击的时候执行方法名为consoleLog的方法。
创建index6.html文件演示v-on指令的使用,index6.html代码内容如2-6所示:
例2-6 index6.html
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <script src="./vue.js"></script>
- <title>Document</title>
- </head>
- <body>
- <div id="app">
- <button @click="consoleLog">点击</button>
- </div>
- <script>
- new Vue({
- el:"#app",
- methods:{
- consoleLog:function (event) {
- console.log(1)
- }
- }
- })
- </script>
- </body>
- </html>
运行结果,当点击按钮时,触发methods中定义的consoleLog方法。以上便是vue中点击事件的绑定,其他事件同理,比如@submit,@blur,@focus等。
2.8 v-model指令
我们首先回忆一下第一章节中我们有介绍过的MVVM,也就是数据的双向绑定,那么vue到底如何实现数据双向绑定呢?本小节我们来学习v-model指令,并且使用此指定实现MVVM。v-model会忽略所有表单元素的value、checked、selected特性的初始值。因为它选择Vue实例数据做为具体的值。
<div id="app">
<input v-model="somebody">
<p>hello {{somebody}}</p>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
somebody:'小明'
}
})
</script>
这个例子中直接在浏览器input中输入别的名字,下面的p的内容会直接跟着变。这就是双向数据绑定。
以上的小例子是v-model的基本使用,除以以外v-model还可使用修饰符进行修饰,比如lazy,number,trim。他们的使用语法如下:
- lazy
默认情况下,v-model同步输入框的值和数据。可以通过这个修饰符,转变为在change事件再同步。
<input v-model.lazy="msg">
- number
自动将用户的输入值转化为数值类型
<input v-model.number="msg">
- trim
自动过滤用户输入的首尾空格
<input v-model.trim="msg">
2.9 v-bind指令
本小节我们学习的重点是如何针对dom对象动态的绑定一个或者多个特性体的值。常用于动态绑定class和style,以及href等。vue提供了v-bind指令实现此效果。v-bind指定拥有自己的简写方式,可以简写为一个冒号“:”。
比如绑定a标签的href属性的核心代码:
html部分:
<div class="app">
<a v-bind:href="url">click me</a>
</div>
vue实例初始化部分:
var app = new Vue({
el:'.app',
data:{
url:"https://www.baidu.com",
}
});
简写方式:
<div class="app">
<a :href="url">click me</a>
</div>
2.10 v-pre & v-cloak & v-once指令
vue中还提供了v-pre,v-cloak,v-once指令,这些指令相对来说使用场景较少,但是也要求开发者进行了解,在特殊各自指令的独特使用场景下进行使用。
2.10.1 v-pre指令
该指令不会解析vue语法,在模板中跳过vue的编译,而是直接把vue代码输出页面。
比如伪代码如下:
msg:"你好啊,今天天气真好"
<div v-pre>{{msg}}</div>
运行效果本来{{list}}是应该输出list属性的值 “你好啊,今天天气真好”,而使用了 v-pre 指令后,就直接输出源代码。
{{list}}
2.10.2 v-cloak指令
这个指令使用机率非常少。vue绑定数据时,渲染时会出现变量闪烁,当网络较慢,网页还在加载 Vue.js ,而导致 Vue 来不及渲染,这时页面就会显示出 Vue 源代码。我们可以使用 v-cloak 指令来解决这一问题。例如:
<div class="#app">
<p>{{value.name}}</p>
</div>
在加载时会看到{{value.name}}在页面出现,过几秒才会渲染数据。而v-cloak就是用来解决这个问题的,如:
<div class="#app" v-cloak>
<p>{{value.name}}</p>
</div>
在css里面要添加:
[v-cloak] {
display: none;
}
不过,实际使用中,我很少看到变量闪烁的情况,这里作为了解即可。
2.10.3 v-once指令
这个指令表示,只渲染一次。
<div v-once>{{massage}}</div>
<input v-model="massage" type="text">
<div>{{massage}}</div>
上面代码中,第一个div中的{{massage}}只渲染一次,当我们在input输入框中修改massge值时,第一个div因使用了v-once指令而不会再发生变化,而第二个div的内容会跟input内容变化而变化。