在 Vue 中,指令都带有 v- 前缀,以表示它们是 Vue 提供的特殊的 attribute,它们会在渲染 DOM 是进行特殊的响应式行为。
Vue 内置了一些常用的指令:
1. v-if 和 v-else 条件渲染指令
2. v-show 条件展示指令;
3. v-for 列表渲染指令;
4. v-bind 条件绑定指令;
5. v-on 事件处理指令;
下面我们来应用一下这些指令的基本使用。
1)内容绑定,事件绑定
1.1)v-text
设置标签文的内容(textContent)
默认写法会替换全部内容,使用差值表达式 {{}} 可以替换指定内容
<!DOCTYPE html> <html lang="en"> <head> <mate charset="UTF-8"></mate> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>v-text</title> <!-- 导入Vue.js --> <script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script> </head> <body> <div id="app"> <h1 v-text="message">你好</h1> <!--Cyan--> <h1 v-text="ah+'!!!'">你好</h1> <!--啊哈哈哈哈哈哈!!!--> <h1>你好呀 {{message+' !'}}!!</h1><!--你好呀 Cyan !!!--> </div> <script> var vm = new Vue({ el: "#app", data: { message: "Cyan", ah: "啊哈哈哈哈哈哈" } }); </script> </body> </html>
1.2)v-html
设置标签的 innerHTML
内容中有 html 结构会被解析为标签
v-text 指令无论内容是什么,只会解析为文本
<!DOCTYPE html> <html lang="en"> <head> <mate charset="UTF-8"></mate> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>v-html</title> <!-- 导入Vue.js --> <script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script> </head> <body> <div id="app"> <p v-text="content"></p> <p v-html="content"></p><!--能转义html标签--> </div> <script> var vm = new Vue({ el: "#app", data: { content: "<a href='http://www.baidu.com' target='_blank'>百度</a>" } }); </script> </body> </html>
1.3)v-on
为元素绑定事件,监听事件。
- 事件名不需要写 on
- 指令可以简写为 @
- 绑定的方法定义在 methods 属性中
<!DOCTYPE html> <html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml"> <head> <mate charset="UTF-8"></mate> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>v-on</title> <!-- 导入Vue.js --> <script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script> </head> <body> <div id="app">
<!--在这里我们使用了 v-on 绑定了 click 事件,并指定了名为 alertTimechangeFood 的方法-->
<input type="button" value="v-on指令" v-on:click="alertTime"> <input type="button" value="v-on简写" @click="alertTime"> <input type="button" value="双击事件" @dblclick="alertTime"> <h2 @click="changeFood">{{food}}</h2> </div> <script> var vm = new Vue({ el: "#app", data: { food: "西红柿 + 鸡蛋 = ?" }, methods: { alertTime: function () { alert(new Date().toLocaleString()); }, changeFood: function () { this.food = "西红柿炒蛋"; alert(this.food); } } }); </script> </body> </html>
2)显示切换,属性绑定
2.1)v-show
根据数据的真假状态切换元素的显示状态
原理是修改元素的 display,实现显示隐藏
指令后面的内容,最终都会解析为布尔值
<!DOCTYPE html> <html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml"> <head> <mate charset="UTF-8"></mate> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>v-show</title> <!-- 导入Vue.js --> <script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script> </head> <body> <div id="app"> <div> <button @click="changFlag">【点击文字改变显示状态】/button> <h2 v-show="flag" style="color: green">你好呀 嘎嘎嘎!!!</h2> </div> <br/> <div> 年龄: <button @click="add">+</button> {{age}} <button @click="sub">-</button> <br/> 小明是否成年? <strong style="color: green" v-show="age>=18">是</strong> <strong style="color: blue" v-show="age<18">否</strong> </div> </div> <script> var vm = new Vue({ el: "#app", data: { flag: false, age: 16 }, methods: { changFlag: function () { this.flag = !this.flag; }, add: function () { this.age++; }, sub: function () { this.age--; } } }); </script> </body> </html>
2.2)v-if
根据表达式的真假,切换元素的显示和隐藏(操纵dom元素)
本质是通过操纵 dom 元素来切换显示状态
表达式的值 为 true 时 元素存在于 dom 树中,为 false 时 从 dom 树中移除
繁的切换时使用 v-show,反之使用 v-if,前者消耗小
<!DOCTYPE html> <html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml"> <head> <mate charset="UTF-8"></mate> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>v-if</title> <!-- 导入Vue.js --> <script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script> </head> <body> <div id="app"> <input type="button" value="切换状态显示" @click="changeDisplay"> <h2 v-if="isShow">这是v-if修饰的</h2><!--当表达式为 true 时,dom 元素才显示--> <h2 v-show="isShow">这是v-show修饰的</h2><!--无论表达式是否为 true 都显示 dom 元素,show 只是修改添加修改样式 display: none;--> </div> <script> var vm = new Vue({ el: "#app", data: { isShow: true }, methods: { changeDisplay: function () { this.isShow = !this.isShow; } } }); </script> </body> </html>
2.3)v-bind
为元素绑定属性(如:src、title、class)
完整写法为 v-bind:属性名
简写为 :属性名
需要动态的增删 class 建议使用对象的方式
<!DOCTYPE html> <html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml" xmlns:v-bind="http://www.w3.org/1999/xhtml"> <head> <mate charset="UTF-8"></mate> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>v-bind</title> <!-- 导入Vue.js --> <script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script> <style> .active {width: 30%;height: 30%; } </style> </head> <body> <div id="app"> <button @click="changeDisplay">切换显示</button> <br/> <img v-bind:src="imgSrc1" v-bind:title="imgTitle1" v-bind:class="isActive?'active':''"> <!-- 三元表达式:isActive?'active':''--> <img :src="imgSrc2" :title="imgTitle2" :class="isActive?'':'active'"><!--简写--> </div> <script> var vm = new Vue({ el: "#app", data: { imgSrc1: "https://wx3.sinaimg.cn/mw690/5301ff11ly1gb58jyz6fgj20p00p0q5g.jpg", imgTitle1: "喵喵警长", imgSrc2: "https://wx3.sinaimg.cn/mw690/5301ff11ly1gb58jwjhikj20p00p0q4l.jpg", imgTitle2: "皮在痒", isActive: false }, methods: { changeDisplay: function () { this.isActive = !this.isActive; } } }); </script> </body> </html>
2.4)图片切换
① 使用 v-bind 绑定 img 的 src 属性来动态显示图片
② 用 v-on 将实现上一页下一页的两个方法绑定到 button 按钮中,button 元素用到了 v-show 指令 当显示图片到达头尾部即不显示按钮。
<!DOCTYPE html> <html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml" xmlns:v-bind="http://www.w3.org/1999/xhtml"> <head> <mate charset="UTF-8"></mate> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Demo-1</title> </head> <body> <!--2.Vue层 模板--> <div id="app" style="margin: 0px 200px"> <button @click="prve" v-show="index>0">上一页</button> <button @click="next" v-show="index<imgArr.length-1" style="float: right">下一页</button> <img :src="imgArr[index]" style="padding: 5px 0px;" width="100%" height="100%"> </div> <!--1.导入Vue.js--> <script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script> <script> var vm = new Vue({ el: "#app", data: { /* 图片集 */ imgArr: [ "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605936390251&di=05c50276b28a39223e375c84dea3fe9f&imgtype=0&src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2Fe%2F564423fb9d994.jpg", "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605936390250&di=229bcd8fba04a0c3ada3a70c57a41ba3&imgtype=0&src=http%3A%2F%2Fimage.imufu.cn%2Fforum%2F201507%2F14%2F112717k2c3ejgqaelj9aa7.jpg", "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605936390250&di=ad2e4ca9e99c3887a1b0d1636da350a8&imgtype=0&src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2F7%2F58f8549329800.jpg", "https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1271003329,4165191310&fm=26&gp=0.jpg", "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605936390250&di=09d8b4a6ef6eeae3d58f32c496b77aec&imgtype=0&src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2F3%2F583e9b8758dd3.jpg", "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605936390249&di=36884556d13a815c5aa5093ba8910766&imgtype=0&src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2F1%2F590c26814e7a3.jpg", "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3465729551,2491385452&fm=26&gp=0.jpg", "https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=3322203117,337153453&fm=26&gp=0.jpg", "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605936390249&di=3c6b7982199fb18d23f824bae344b120&imgtype=0&src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2F6%2F5984113d8db74.jpg", ], /* 显示索引 */ index: 0 }, methods: { /* 上一页 */ prve: function () { if (this.index > 0) this.index -= 1; else this.index = this.imgArr.length - 1; }, /* 下一页 */ next: function () { if (this.index < this.imgArr.length - 1) this.index += 1; else this.index = 0; } } }); </script> </body> </html>
3)列表循环,表单元素绑定
3.1)v-for
根据数据生成列表结构
该指令一般都是和数组结合使用的
语法:(item,index) in 数据
item 和 index 可以结合其它指令一起使用
数组长度的更新会响应式的同步到页面上
<!DOCTYPE html> <html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml" xmlns:v-bind="http://www.w3.org/1999/xhtml"> <head> <mate charset="UTF-8"></mate> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>v-for</title> <!-- 导入Vue.js --> <script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script> </head> <body> <div id="app">遍历普通数组: <ul> <li v-for="(item,index) in arr">索引:{{index+1}} - 城市:{{item}}</li> </ul> 遍历对象数组: <input type="button" value="添加数据" @click="add"> <input type="button" value="删除数据" @click="remove"> {{vagetables}} <ul> <li v-for="item in vagetables">{{item.name}}</li> </ul> </div> <script> var vm = new Vue({ el: "#app", data: { arr: ["北京", "上海", "广州", "深圳", "杭州", "福建", "天津", "哈尔滨", "武汉", "西藏"], vagetables: [{name: "火山飘雪"}, {name: "粉身碎骨小青龙"}, {name: "黑白无常"}, {name: "沉默的羔羊"}, {name: "青龙卧雪"}, {name: "绝代双骄"}, {name: "热情小炒肉"}] }, methods: { add: function () { this.vagetables.push({name: "一个小菜"}); }, remove: function () { // alert("删除 " + this.vagetables.shift().name); /* 弹出队首 */ alert("删除 " + this.vagetables.pop().name); /* 弹出队尾 */ } } });</script> </body> </html>
3.2)v-on
为元素绑定事件
事件绑定的方法写成 函数调用 的形式,可以传入自定义参数
定义方法时需要定义 形参 来接收传入的实参
可以使用 @keyup.修饰符 来对事件进行限制
@keyup.enter 可以限制触发的按键为回车键
事件修饰符有多种
<!DOCTYPE html> <html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml" xmlns:v-bind="http://www.w3.org/1999/xhtml"> <head> <mate charset="UTF-8"></mate> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>v-on</title> <!-- 导入Vue.js --> <script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script> </head> <body> <div id="app"> <input type="button" value="点击" @click="sayHi('铁汁','小伙纸')"><!--可以输入参数--> <input type="text" @keyup.enter="method('哈喽')"><!--绑定回车键--> </div> <script> var vm = new Vue({ el: "#app", methods: { sayHi: function (s1, s2) { alert("你好 " + s1 + " !") alert("你好 " + s2 + " !") }, method: function (str) { alert(str); } } }); </script> </body> </html>
3.3)v-model
获取和设置表单元素的值(双向数据绑定)
绑定的数据会和表单元素的值相关联
绑定的数据 ← → 表单元素的值
<!DOCTYPE html> <html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml" xmlns:v-bind="http://www.w3.org/1999/xhtml"> <head> <mate charset="UTF-8"></mate> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>v-model</title> <!-- 导入Vue.js --> <script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script> </head> <body> <div id="app"> <input type="text" v-model="message" @keyup.enter="getMsg" placeholder="输入后按回车键弹出"/> <h2 style="text-align: center;color: green"> ↓↓↓ 双向同步显示 ↓↓↓ <br/> {{message}} </h2> </div> <script> var vm = new Vue({ el: "#app", data: { message: "" }, methods: { getMsg: function () { alert(this.message); } } }); </script> </body> </html>
3.4)记事本
使用上面所学指令,实现一个记事本。
<!DOCTYPE html> <html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml" xmlns:v-bind="http://www.w3.org/1999/xhtml"> <head> <mate charset="UTF-8"></mate> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>记事本</title> <!-- 导入Vue.js --> <script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script> </head> <style> #app {width: 650px;min-height: 280px;margin: 0 auto;border: 5px outset rgb(209 224 227);background: beige;} /* header */ .header h1 {text-align: center;color: #ffffff;background-color: rgb(200 220 221)} .header input {margin-left: 482px;width: 150px;} /* content */ table {margin: auto; /*垂直居中*/text-align: center; /*文字居中*/width: 88%; /*宽度*/font-family: verdana, arial, sans-serif;font-size: 11px;color: #333333;border-width: 1px;border-color: #999999;border-collapse: collapse;} table th {background: #b5cfd2 url('cell-blue.jpg');border-width: 1px;padding: 8px;border-style: solid;border-color: #999999;} table td {background: #dcddc0 url('cell-grey.jpg');border-width: 1px;padding: 8px;border-style: solid;border-color: #999999;} /* 统计 */ .census {text-align: right;font-size: 0.7em;padding-right: 10px;} /* footer */ .footer {color: #a0a0a0;text-align: center;font-size: 0.3em;} </style> <body> <!-- 主体区域 --> <div id="app"> <!-- 输入框 --> <div class="header"> <h1>记事本</h1> <!-- vue 监听键盘回车事件 --> <input type="text" v-model="msg" placeholder="添加任务 回车键确认" @keyup.enter="setMsg"/> </div> <hr> <!-- 列表区域 --> <table> <tr> <th>序号</th> <th>任务</th> <th>操作</th> </tr> <tr v-if="messages.length>0" v-for="(item,index) in messages"> <td>{{index+1}}</td> <td>{{item}}</td> <td> <button @click="delMsg(index)">delete</button> </td> </tr> <tr v-if="messages.length<=0"> <td>-</td> <td>-</td> <td></td> </tr> </table> <hr> <!-- 统计和清空任务 --> <div class="census"> <!-- 表示数组的元素不为0时才显示 --> <span> <!-- 统计任务 - 显示数组长度 --> <strong>{{messages.length}}</strong> items left </span> <!-- 清空任务 - 数组置空 --> <button @click="delMsgs" :style="messages.length>0?'cursor: pointer':'cursor: not-allowed'">Clear </button> </div> <!-- 底部 --> <hr> <div class="footer"> <p> Copyright © 2020 青 · 大漠孤烟 <br/> Powered by .VUE 2.6.12 </p> </div> </div> <script> var vm = new Vue({ el: "#app", data: { msg: "", messages: [] }, methods: { setMsg: function () { this.messages.push(this.msg);/* 将数据添加到数组中 */ this.msg = "";/* 清空输入框数据 */ }, delMsg: function (index) { this.messages.splice(index, 1); /* 删除指定下标起的1个元素 */ }, delMsgs: function () { if (this.messages.length > 0) this.messages = []; /* 将数组置空,实现清空数据 */ } } }); </script> </body> </html>