指令
指令的概念(6种)
指令(Directives)是vue为开发者提供的模版语法,用于辅助开发者渲染页面的基本结构。
按照不同的用途可以分为以下6大类
-
内容渲染指令
-
属性绑定指令
-
事件绑定指令
-
双向绑定指令
-
条件渲染指令
-
列表渲染指令
1. 内容渲染指令p37
内容渲染指令用来辅助开发者渲染DOM元素的文本内容,常用的内容渲染指令有三个
-
v-text
-
{{}}
-
V-html
v-text
缺点:v-text指令会覆盖原本内部的内容。
<div id="app"> <p v-text="username"></p> <!-- v-text指令会覆盖原本内部的内容 --> <p v-text="gender">gender:</p> <p>xingbie </p> </div> <script src="./lib/vue-2.6.12.js"></script> <script> const vm = new Vue({ el:'#app', data:{ username:'mingzi', gender:'male' } }) </script>
{{}}
差值表达式(Mustache),专门用来解决v-text指令会覆盖原本内部的内容的问题。
使用最多,一个类似${}
的内容的占位符。
差值表达式只能用在内容节点,而非属性节点(eg:placeholder="{{}}"无法正常显示且会报错)。
<!-- 只能写一个id="app"的div,写第二个会被无视 --> <div id="app"> <p v-text="username"></p> <p v-text="gender">gender:</p> <hr> <p>username:{{username}}</p> <p>gender:{{ gender }}</p> </div> <script src="./lib/vue-2.6.12.js"></script> <script> const vm = new Vue({ el:'#app', data:{ username:'mingzi', gender:'male' } }) //el可以被vm.$mount('app')替代。 </script>
V-html
可以把带有标签的字符串渲染成真正的HTML内容
<!-- 只能写一个id="app"的div,写第二个会被无视 --> <div id="app"> <p v-text="username"></p> <p v-text="gender">gender:</p> <hr> <p>username:{{username}}</p> <p>gender:{{ gender }}</p> <hr> <div v-text="info"></div> <div>{{ info }}</div> <div v-html="info"></div> </div> <script src="./lib/vue-2.6.12.js"></script> <script> const vm = new Vue({ el:'#app', data:{ username:'mingzi', gender:'male', info:'<h4 style="color: red;font-weight: bold ;">this is info</h4>' } }) </script>
2.属性绑定指令
v-bind:/:
为元素的属性动态绑定属性值。
vue规定,'v-bind:'可以简写为':'
如果绑定内容需要动态拼接,则字符串的外面应该包裹单引号,见2.5
示例
<body> <div id="app"> <input type="text" :placeholder="tips"> </div> <!-- 导入vue的库文件,在window全局就有了Vue这个构造函数 --> <script src="../lib/vue-2.6.12.js"></script> <script> //创建vue的实例对象 const vm = new Vue({ //固定写法 el: '#app', data: { //1.将tips里的值渲染到placeholder中 tips: "keyin" }, methods: { } }) </script> </body>
2.5在差值和属性绑定中写js表达式
在vue的模版渲染语法中,除了支持绑定简单的数据值之外,还支持js表达式的运算。
{{number+1}}
{{ok?1:0}}
{{message.split('').reverse().join('')}}
//字符串倒过来:字先分割为数组再反转再拼
<div v-bind:id="'list-'+id"></div>
3.事件绑定指令
v-on
v-on事件绑定指令,辅助开发者完成DOM元素绑定事件监听。
on+原生事件:v-on:keyup
示例
<body> <div id="app"> <p>count is {{ count }}</p> <!-- 格式:v-on:事件名称="事件处理函数的名称" --> <button v-on:click="addCount">+1</button> </div> <!-- 导入vue的库文件,在window全局就有了Vue这个构造函数 --> <script src="../lib/vue-2.6.12.js"></script> <script> //创建vue的实例对象 const vm = new Vue({ //固定写法 el: '#app', data: { count: 0, }, methods: { //addCount: function () { addCount(){//简写 //this=vm构造函数 this.count += 1 } } }) </script> </body>
绑定事件并传参
<body> <div id="app"> <p>count is {{ count }}</p> <!-- 格式:v-on:事件名称="事件处理函数的名称" --> <!-- 小括号传递参数 --> <button v-on:click="addCount(9)">+1</button> </div> <!-- 导入vue的库文件,在window全局就有了Vue这个构造函数 --> <script src="../lib/vue-2.6.12.js"></script> <script> //创建vue的实例对象 const vm = new Vue({ //固定写法 el: '#app', data: { count: 0, }, methods: { //addCount: function () { addCount(n){//简写 this.count += n } } }) </script> </body>
@
'v-on:'简写为'@'(去掉'')
$event
当事件处理函数没有绑定变量,那么自带事件对象e,eg:
methods: { //addCount: function () { addCount(e){//简写 this.count++ if (this.count%2==0) { e.target.style.backgroundColor = 'red' } } }
但是当当事件处理函数绑定了变量,这时候vue提供了内置变量,名字叫做$event,它就是原生的DOM的事件对象e,这个$event是固定写法。
<body> <div id="app"> <p>count is {{ count }}</p> <!-- 格式:v-on:事件名称="事件处理函数的名称" --> <!-- 小括号传递参数 --> <!-- n和$event顺序无所谓,但是下方函数要和这里顺序相同 --> <button v-on:click="addCount(99,$event)">+1</button> </div> <!-- 导入vue的库文件,在window全局就有了Vue这个构造函数 --> <script src="../lib/vue-2.6.12.js"></script> <script> //创建vue的实例对象 const vm = new Vue({ //固定写法 el: '#app', data: { count: 0, }, methods: { //addCount: function () { addCount(n,e){//简写 this.count+=n if (this.count%2==0) { e.target.style.backgroundColor = 'red' }else{ e.target.style.backgroundColor = '' } } } }) </script> </body>
事件修饰符
在原生中,阻止表单/链接自动跳转用e.preventDefault()
,阻止冒泡e.stopPagation()
vue提供了更简单的写法
<a href:"url" @click.prevent="name">跳转</a>
事件修饰符用来更简便的对事件的触发进行控制,常用的五个如下:
事件修饰符 | 说明 |
---|---|
.prevent | 阻止默认行为(阻止链接跳转,表单提交等)。 |
.stop | 阻止事件冒泡。 |
.capture | 以捕获模式触发当前的事件处理函数。 |
.once | 绑定的事件只触发一次。 |
.self | 只有在e.target是当前元素自身时触发事件处理函数。 |
按键修饰符
在监听键盘事件时,经常需要判断详细的按键,可以为键盘相关事件添加按键修饰符:
<input @keyup.enter='submit'>
// 只有在'key'是'Enter'时调用submit()
<input @keyup.esc='clearInput'>
//只有在'key'是'Esc'时调用clearInput()
示例
<body> <div id="app"> <input type="text" @keyup.esc="clearInput"> </div> <!-- 导入vue的库文件,在window全局就有了Vue这个构造函数 --> <script src="../lib/vue-2.6.12.js"></script> <script> //创建vue的实例对象 const vm = new Vue({ //固定写法 el: '#app', data: { }, methods: { clearInput(e){//这个e必须写 e.target.value='' } } }) </script> </body>
4.双向绑定指令
v-model
vue提供了v-model双向数据绑定指令,在不操作dom的前提下,快速获得表单的数据。
只能表单元素使用:input,textarea,select。
可以理解为有value属性的就可以使用。
示例
<div id="App"> <p>{{ username }}</p> <input type="text" v-model="username "><hr> <input type="text" :value="username"><hr> <select v-model="city"> <option value="11">choose please</option> <option value="22">bei</option> <option value="33">shang</option> <option value="44">guang</option> </select> </div> <script src="../components/lib/vue-2.6.12.js"></script> <script> //Vue.config.devtools = true; const vm = new Vue({ el:"#App", data:{ username:'aaa', city:'22', }, }) </script>
v-model指令的修饰符
修饰符 | 作用 | 示例 |
---|---|---|
.number | 自动将用户输入的值转为数值类型 | <input v-model.number="age"/> |
.trim | 自动过滤用户输入的空白字符 | <input v-model.trim="msg"/> |
.lazy | 在'change'时而非'input'时更新 | <input v-model.lazy="msg"/> |
注意:例如.number修饰符改变的是用户输入的值,而非data里的初始值。
示例
<div id="App"> <input type="text" v-model.number="n1">+<input type="text" v-model.number="n2"> = <span>{{n1+n2}}</span> </div> <script src="../components/lib/vue-2.6.12.js"></script> <script> Vue.config.devtools = true; const vm = new Vue({ el:"#App", data:{ username:'aaa', //city:'22', n1:1, n2:2, }, }) </script>
5.条件渲染指令
v-if/v-show
条件渲染指令用来辅助开发者按需控制DOM的显示与隐藏,分别为v-if/v-show
V-if=flase 是动态删除掉了元素。
如果刚进入页面,某些元素默认不需要被展示,而且后期这个元素也不一定需要被展示,这时用v-if性能更好。
v-show=false 是给元素加上了display:none;
这个属性进行隐藏。
如果要频繁的切换元素的显示状态,用v-show性能会更好
示例
<div id="app"> <p v-if="networkState === 200">请求成功,被v-if控制</p> <p v-show="networkState === 200">请求成功,被v-show控制</p> </div>
<div id="App"> <p v-if="flag">v-if</p> <p v-show="flag">v-show</p> </div> <script src="./lib/vue-2.6.12.js"></script> <script> const vm = new Vue({ el:"#App", data:{ // 若flag为true,则显示被控制的元素,如果为false则隐藏被控制的元素。 flag:true, }, }) </script>
v-else-if/v-else
作为v-if的 “else-if块”,可以连续使用:
注意!v-else-if指令必须配合v-if一起使用,否则将无法被识别。
<div v-if="grade>=90">A</div> <div v-else-if="grade>=80">B</div> <div v-else-if="grade>=60">C</div> <div v-else>D</div>
6.列表渲染指令
v-for
v-for列表渲染指令,基于一个数组循环来渲染一个列表结构;
v-for指令需要 item in items 形式的特殊语法。
item:被循环的每一项
items:待循环的数组
示例
<ul> <li v-for="item in list">{{ item.name }}</li> </ul> ... data:{ list:[//列表数据 {id:1,name:'aaa'} {id:2,name:'bbb'} ] }
V-for的index
v-for 指令还支持可选的第二个参数index,即当前项的索引。
语法格式为 (item,index) in items
注意:item项与index索引值都为形参,可以根据需要进行重命名,例如:(user,i) in userlist
:key
建议:在使用了v-for指令,一定要绑定一个:key
属性:提升性能,防止列表紊乱。
并且尽量把id作为key的值:key='item.id'
; id的值具有唯一性。
key的值的类型要求为:string或number。
key的值不能重复(唯一性),否则会终端报错。错误代码:'duplicate keys detected'。
使用index作为key值无意义,因为index的值不唯一:id和数据绑定,但是index和位置绑定,位置上的数据不稳定,例如使用unshift给列表前加上项,之前index项对应的数据会往后延,即index的值不唯一。
综合示例
<head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="./lib/bootstrap.css"> </head> <body> <div id="App"> <ul> <li v-for="item in list" :key="item.id">{{ item.name }}</li> </ul> <table class="table table-bordered table-hover table-striped"> <thead> <th>index</th> <th>id</th> <th>name</th> </thead> <tbody> <!-- 要循环谁就给谁加 --> <tr v-for="(item,index) in list" :key="item.id"> <td>{{index}}</td> <td>{{item.id}}</td> <td>{{item.name}}</td> </tr> </tbody> </table> </div> <script src="./lib/vue-2.6.12.js"></script> <script> const vm = new Vue({ el: '#App', data: { list: [//列表数据 { id: 1, name: 'aaa' }, { id: 2, name: 'bbb' }, { id: 3, name: 'ccc' } ] } }) </script> </body>