指令(Directives)是带有”v-“前缀的特殊属性。每一个指令在vue中都有固定的作用。

在vue中,提供了很多指令,常用的有:v-if、v-model、v-for等等。

指令会在vm对象的data属性的数据发生变化时,会同时改变元素中的其控制内容或属性。

因为vue的历史版本原因,所以一部分指令都有两种写法:

left

第一种写法

1
2
3
4
v-html="html代码"		
{{ 普通文本 }}
:属性名="属性值"
@事件名="js代码"

right

第二种写法

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>
/*ctrl + shift + j 多行代码合并到一行*/
.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>
<!-- 这里的v-model是什么意思为什么要在这里写,
而且这个写的是否显示后,再次点击输入框会变得只能在第一个位置输入,
虽然可以通过左右键来调整-->
<!--这里的v-model可以时后台获取对应的文本内容-->
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>
<!-- @click的值既可以是js代码,也可以是methods中定义的方法,如dianzan2()括号内无需参数,则可以省略 -->
<button @click="dianzan3(2)">点赞4({{num4}})</button>
<!-- 含参↑-->
<br>
<!-- 写法四-->
<!-- .once修饰符表示只执行一次-->
<button @click.once="dianzan1">点赞2({{num2}})</button>
</div>
<script>
vm = Vue.createApp(
{
data() {
return {
num1: 0,
num2: 0,
num3: 0,
num4: 0,
// dianzan1: 0
// methods和data中的变量名不能一样否则出错,错误信息如下
// vue.3.3.4.js:1516 [Vue warn]: Data property "dianzan1" is already defined in Methods.
// at <App>
}
},
methods: {
dianzan1() {
this.num2 += 1

}, dianzan2() {
if (this.num3 < 1) {
this.num3 += 1
}

}, dianzan3(n) {
this.num4 += n
}
}
}
).mount("##app")
</script>
</body>
</html>

##完成商城购物车中的商品增加减少数量

步骤:

  1. 给vue对象添加操作数据的方法

  2. 在标签中使用指令调用操作数据的方法

    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><!--不加单引号就是变量,因为默认值是json,或者2使用驼峰式的命名方式-->
<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;
/*设置当前元素的显示模式为块级/块状
/*background-color: gray;*/
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==='体育新闻'}" @click="current_title='体育新闻'">体育新闻</span>-->
<!-- <span :class="{current:current_title==='财政资讯'}" @click="current_title='财政资讯'">财政资讯</span>-->
<!-- <span :class="{current:current_title==='娱乐八卦'}" @click="current_title='娱乐八卦'">娱乐八卦</span>-->
<!-- </div>-->
<!-- <div class="contentbox">-->
<!-- &lt;!&ndash; <div class="content active" :class="current_title==='体育新闻'?'active':''">体育新闻</div>&ndash;&gt;-->
<!-- <div :class="{content:true,active:current_title==='体育新闻'}">体育新闻</div>-->
<!-- <div :class="{content:true,active:current_title==='财政资讯'}">财政资讯</div>-->
<!-- <div :class="{content:true,active:current_title==='娱乐八卦'}">娱乐八卦</div>-->
<!-- </div>-->
<!--</div>-->
<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 active" :class="current_title==='体育新闻'?'active':''">体育新闻</div>-->
<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大致一样,区别在于两点:

  1. v-show后面不能使用v-else或者v-else-if

  2. 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,key in book">&lt;!&ndash;jinja2语法和Django的for模板语法差不多&ndash;&gt;-->
<!-- 可行但是会有报错提示-->
<tr v-for="(role,rank) in book"><!--加入(可以避免报错,也是官方建议的写法)-->

<td>##{{rank + 1}}</td><!--获取当前次数-->
<!-- <td>##{{rank}}</td>&lt;!&ndash;获取当前次数&ndash;&gt;-->
<!-- <td>##{{book.length-key}}</td>&lt;!&ndash;倒序&ndash;&gt;-->
<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 v-for="(key,value) in roles.attrs">&lt;!&ndash;v-for可以放在这个位置也可以放在下面的位置,不过放在上面是循环ul对象&ndash;&gt;-->
<ul>
<li v-for="(key,value) in roles.attrs">{{key + ':' + value}}</li>
<!-- <li>{{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>

本破站由 @BXZDYG 使用 Stellar 主题创建。
本博客部分素材来源于网络,如有侵权请联系1476341845@qq.com删除
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

本"页面"访问 次 | 👀总访问 次 | 总访客
全部都是博主用心学编写的啊!不是ai啊 只要保留原作者姓名并在基于原作创作的新作品适用同类型的许可协议,即可基于非商业目的对原作重新编排、改编或者再创作。