指令(Directives)是带有”v-“前缀的特殊属性。每一个指令在vue中都有固定的作用。
在vue中,提供了很多指令,常用的有:v-if、v-model、v-for等等。
指令会在vm对象的data属性的数据发生变化时,会同时改变元素中的其控制内容或属性。
因为vue的历史版本原因,所以一部分指令都有两种写法:
第一种写法
1 2 3 4
| v-html="html代码" {{ 普通文本 }} :属性名="属性值" @事件名="js代码"
|
第二种写法
1 2 3 4
| 无 v-text="普通文本" v-bind:属性名="属性值" v-on:事件名
|
官方文档:内置指令 | Vue.js (vuejs.org)
vue的指令无就是针对html文档中的属性,标签文本,事件,样式和数据进行操作和页面控制
属性操作
格式:
1
| <标签名 : 标签属性="data属性"></标签名>
|
示例
##通过计时器实现图片切换
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.3.3.4.js"></script> <style> .btn { width: 500px; height: 100%; border: 1px solid red; padding: 3px; } </style> </head> <body> <div id="box" class="btn"> <img :src="img_url" :alt="img_alt"> </div> <script> vm = Vue.createApp({ data() { return { img_alt: "这是一张图片", img_url: "./static/register_font.png", } }, mounted() { setInterval(() => { if (this.img_url === "./static/register_font.png") { this.img_url = "./static/success_font.png" } else { this.img_url = "./static/register_font.png" } }, 1000) } }).mount("##box") </script> </body> </html>
|
##实现密显示和隐藏
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.3.3.4.js"></script> <style> .pwd { width: 140px; margin-right: 6px; }
.btn { cursor: pointer; user-select: none; } </style> </head> <body> <div id="app" class="btn"> <label for="user">账号:<input type="text" v-model="user" id="user"></label> <br> <label for="password">密码:<input :type="pwd_type" v-model="password" id="password" class="pwd" @click="pwd_type=(pwd_type==='password'?text:'password')"><span>
class="btn">&##128064;</span></label> </div> <script> vm = Vue.createApp({ data() { return { pwd_type: "password" } }, mounted() { } }).mount("##app") </script> </body> </html>
|
表单输入绑定 | Vue.js (vuejs.org)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <script setup> import { ref } from 'vue'
const checkedNames = ref([]) </script>
<template> <div>Checked names: {{ checkedNames }}</div>
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames" /> <label for="jack">Jack</label> <input type="checkbox" id="john" value="John" v-model="checkedNames" /> <label for="john">John</label> <input type="checkbox" id="mike" value="Mike" v-model="checkedNames" /> <label for="mike">Mike</label> </template>
|
事件绑定
有两种事件操作的写法,@事件名 和 v-on:事件名
1 2
| <button v-on:click="num++">按钮1</button> <button @click="num+=5">按钮2</button>
|
说明:
1 2 3 4 5 6 7 8 9
| 1.使用@事件名来进行事件的绑定 语法: <h1 @click="num++">{{num}}</num> 2.绑定的事件的事件名,全部都是js的事件名: @submit --> onsubmit 表单提交事件 @focus --> onfoucs 获取焦点事件 @blur --> onblur 失去焦点事件 @click --> onclick 点击事件 ...
|
示例:
##点击事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.3.3.4.js"></script> </head> <body> <div id="app"> <button @click="num1++">点赞1({{num1}})</button> <br> <button @click="dianzan1">点赞2({{num2}})</button> <br> <button @click="dianzan2">点赞3({{num3}})</button> <button @click="dianzan3(2)">点赞4({{num4}})</button> <br> <button @click.once="dianzan1">点赞2({{num2}})</button> </div> <script> vm = Vue.createApp( { data() { return { num1: 0, num2: 0, num3: 0, num4: 0, } }, methods: { dianzan1() { this.num2 += 1
}, dianzan2() { if (this.num3 < 1) { this.num3 += 1 }
}, dianzan3(n) { this.num4 += n } } } ).mount("##app") </script> </body> </html>
|
##完成商城购物车中的商品增加减少数量
步骤:
给vue对象添加操作数据的方法
在标签中使用指令调用操作数据的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.3.3.4.js"></script> <style> table, tr, td { border: 1px solid red; border-collapse: collapse; }
td { width: 120px; text-align: center; vertical-align: center; }
.btn { width: 40px; text-align: center; } </style> </head> <body> <div id="app"> <table> <tr> <td>商品价格</td> <td>商品价格</td> <td>商品库存</td> <td>购买数量</td> <td>商品小计</td> </tr> <tr> <td>python入门</td> <td>{{good_price}}</td> <td>{{has_num}}</td> <td> <button @click="num--">-</button> <input class="btn" type="text" v-model="num"> <button @click="num++">+</button> </td> <td>{{(num * good_price).toFixed(2)}}</td> </tr> <tr> <td>python爬虫</td> <td>{{good_price}}</td> <td>{{has_num}}</td> <td> <button @click="sub_num">-</button> <input class="btn" type="text" v-model="num"> <button @click="add_num">+</button> </td> <td>{{(num * good_price).toFixed(2)}}</td> </tr> <tr> <td>django</td> <td>30000</td> <td>{{has_num}}</td> <td> <button @click="num--">-</button> <input class="btn" type="text" v-model="num"> <button @click="num++">+</button> </td> <td>{{(num * good_price).toFixed(2)}}</td> </tr> </table> </div> <script> vm = Vue.createApp( { data() { return { num: 0, has_num: 100, good_price: 29.9 } }, methods: { sub_num() { if (this.num >= 1) { this.num -= 1 } }, add_num() { if (this.num < this.has_num) { this.num += 1 } } } } ).mount("##app") </script> </body> </html>
|
思考和缺陷:无法不通过枚举设置之操作一个tb里面的数据,而获取的数据又如何通过打包。用户不通过按钮手动输入数据变成字符串后,再加减就是字符串拼接操作
操作样式
操作样式,本质上就是属性操作,使用冒号:
控制标签class类名
格式
1
| <h1 :class="值">元素</h1> 值可以是字符串、对象、对象名、数组
|
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.3.3.4.js"></script> </head> <style> .cls1 { color: blue; }
.cls2 { background-color: orange; } </style> <body> <div id="app"> <ul> <li class="cls1">1</li> <li class="cls1 cls2">2</li> <li :class="exterior1">3</li> <li :class="[exterior1,exterior2]">4</li> <li :class="{cls1:true,cls2:is_add_true}">5</li> <li :class="{cls1:true,cls2:is_add_true}" @click="chang_cls2">5+1</li> <li :class="exterior3" @click="is_add_true=!is_add_true">5+2</li> </ul> </div>
<script> vm = Vue.createApp( { data() { return { exterior1: "cls1", exterior2: "cls2", is_add_true: true, exterior3:{ cls1:true, cls2:false } } }, methods: { chang_cls2() { this.is_add_true = !this.is_add_true; } } } ).mount("##app") </script> </body> </html>
|
控制标签style样式(一般开发不用这个)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| 格式1:值是json对象,对象写在元素的:style属性中 标签元素: <div :style="{color:activeColor,fontSize:fontSSize +'px'}"></div> data数据如下: data:{ activeColor:"red", fontSize:30 } 格式2:值是对象变量名,对象在data中进行声明 标签元素: <div v-bind:style="styleObject"></div> data数据如下: data:{ styleObject:{ color:"red", fontSize:"13px" } } 格式3:值是数组 标签元素: <div v-bind:style="[style,style]"></div> data数据如下: data:{ style1:{ color:"red" },style1:{ background:"yellow", fontSize:"21px" } }
|
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.3.3.4.js"></script> </head>
<body> <div id="app"> <ul> <li style="background-color: orange">第一个</li> <li style="background-color: orange;color: cornflowerblue">第二个</li> <li :style="{'background':'orange'}">第三个</li> <li :style="{backgroundColor:'orange'}">第四个</li> <li :style="{backgroundColor:bgcolor}">第四个+1</li> <li :style="{backgroundColor:'orange',color:'cornflowerblue'}">第五个</li> <li :style="[sty1,sty2]">第六个</li> <li :style="sty1" @click="chang_color">第七个</li> </ul> </div>
<script> vm = Vue.createApp( { data() { return { bgcolor:'orange', sty1:{backgroundColor:'orange',color:'cornflowerblue',userSelect:'none'}, sty2: {width:100+'px'}, } }, methods: { chang_color() { if(this.sty1.color==='cornflowerblue'){ this.sty1.color='red'; }else { this.sty1.color='cornflowerblue'; } } } } ).mount("##app") </script> </body> </html>
|
实例-vue版本选项卡
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>选项卡</title> <script src="./js/vue.3.3.4.js"></script> <style> ##option-card .titlebar span { height: 32px; width: 100px; display: block;
text-align: center; text-decoration: none; vertical-align: middle; line-height: 32px; background-color: ##afafaf; color: ##000; float: left; margin-right: 4px; }
##option-card .titlebar:after { clear: both; display: block; content: ""; }
##option-card .contentbox .content { width: 500px; height: 350px; background-color: yellow; display: none; }
##option-card .contentbox .active { display: block; }
##option-card .titlebar .current { background-color: yellow; } </style> </head> <body>
<div id="option-card"> <div class="titlebar"> <span :class="{current:current_title===0}" @click="current_title=0">体育新闻</span> <span :class="{current:current_title===1}" @click="current_title=1">财政资讯</span> <span :class="{current:current_title===2}" @click="current_title=2">娱乐八卦</span> </div> <div class="contentbox"> <div :class="{content:true,active:current_title===0}">体育新闻</div> <div :class="{content:true,active:current_title===1}">财政资讯</div> <div :class="{content:true,active:current_title===2}">娱乐八卦</div> </div> </div> <script> vm = Vue.createApp({ data() { return { current_title: 0, } } }).mount("##option-card") </script> </body> </html>
|
效果展示
条件渲染指令
v-if,v-else-if,v-else
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 标签元素 <div id="box"> <p v-if="is_login">尊贵的游客欢迎来到我们的网站</p> <p v-else>尊敬的会员欢迎来到我们的网站</p><!--要贴合在v-if的后面,就是于前面一个v-if存在关联,不会受注释影响--> <p v-if="!is_login">尊敬的会员欢迎来到我们的网站</p> <button @click="is_login=!is_login">登录/登出</button> </div>
data 数据 data() { return { is_login:true//表示登录与否,ture未登录,flase登录 } },
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 标签元素 <div id="box"> <p v-if="role===1">尊敬的会员欢迎来到我们的网站</p> <p v-else-if="role===2">尊敬的vip会员欢迎来到我们的网站</p><!--要贴合在v-if的后面,就是于前面一个v-if存在关联,不会受注释影响--> <p v-else>尊贵的游客欢迎来到我们的网站</p> <button @click="role=0">登出</button> <button @click="role=1">登录</button> <button @click="role=2">充vip</button> </div>
data 数据 data() { return { role:0 } }
|
v v-if,v-else-if,v-else多层嵌套
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| 标签元素 <div id="box"> <div v-if="role===0"> <p>尊贵的游客欢迎来到我们的网站</p> <p>您还尚未登录</p> </div> <div v-else> <p v-if="role===1">尊敬的会员欢迎来到我们的网站</p> <p v-else-if="role===2">尊敬的vip会员欢迎来到我们的网站</p> <!--要贴合在v-if的后面,就是于前面一个v-if存在关联,不会受注释影响--> <button @click="role=2">充vip</button> </div> <button @click="role=0">登出</button> <button @click="role=1">登录</button> </div>
data 数据 data() { return { role:0 } }
|
v-show
用法和v-if大致一样,区别在于两点:
v-show后面不能使用v-else或者v-else-if
v-show隐藏元素时,使用的时display:none来隐藏的,而v-if是直接从HTML文档中移除元素[DOM操作中的remove]
1 2 3 4 5 6 7 8 9 10 11
| 标签元素 <div id="box"> <p v-show="is_show">登陆成功</p><!--is_show等于true v-show的作用相当于给标签添加了一个样式style="display: none;使标签不可见--> <button @click="is_show=!is_show">登陆/登出</button> </div> data数据 data() { return { is_show:true } },
|
列表渲染指令
在vue中,可以通过v-for指令将一组数据渲染到页面中,数据可以是数组或者对象
数据是数组时
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.3.3.4.js"></script> <style> table, tr, th, td { text-align: center; border-collapse: collapse; border: 1px solid red; }
th, td { width: 120px; height: 32px; line-height: 32px; vertical-align: center; } </style> </head> <body> <div id="box"> <table> <tr> <th>序号</th> <th>ID</th> <th>姓名</th> <th>年龄</th> <th>性别</th> </tr> <tr v-for="(role,rank) in book">
<td>##{{rank + 1}}</td> <td>{{role.id}}</td> <td>{{role.name}}</td> <td>{{role.age}}</td> <td v-if="role.sex">男</td> <td v-else>女</td> </tr> </table> </div> <script> vm = Vue.createApp({ data() { return { book: [ { "id": 1, "name": "男主", "age": 18, 'sex': true }, { "id": 7, "name": "女主", "age": 19, 'sex': false }, { "id": 9, "name": "女2", "age": 19, 'sex': false }, { "id": 11, "name": "女儿", "age": 9, 'sex': false }, { "id": 13, "name": "完结撒花", "age": 50, 'sex': true } ] } }, methods() { }, mounted() { }, }).mount("##box") </script> </body> </html>
|
数据是对象时
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.3.3.4.js"></script> <style> table, tr, th, td { text-align: center; border-collapse: collapse; border: 1px solid red; }
th, td { width: 120px; height: 32px; line-height: 32px; vertical-align: center; } </style> </head> <body> <div id="box"> <ul> <li>人物ID:{{roles.id}}</li> <li>人物姓名:{{roles.name}}</li> <li>背景信息:
<ul> <li v-for="(key,value) in roles.attrs">{{key + ':' + value}}</li>
<li>{{key+':'+value}}</li> </ul> </li> <li>年龄:{{roles.age}}</li> <li v-if="roles.sex===true">性别: 男</li> <li v-else>性别: 女</li> </ul> </div> <script> vm = Vue.createApp({ data() { return { roles: { "id": 1, "name": "男主", attrs: { '生活世界': '异世界', '能力品阶': 180, '穿越时间': '2023年8月3日' }, "age": 18, 'sex': true }, } }, methods() { }, mounted() { }, }).mount("##box") </script> </body> </html>
|