目录
一. 绑定语法: 学名: 插值语法 Interpolation
二. 指令(directive)
1. v-bind
2. v-show
3. v-if和v-else
4. v-else-if
5. v-for
💥 扩展:this判断—8种指向
⬛ 总结:知识点提炼
一. 绑定语法: 学名: 插值语法 Interpolation
1. 什么是: 在界面中标记哪里可能发生变化的特殊的语法
2. 何时: 今后,只要一个元素的内容希望随程序自动变化时,都要用绑定来标记
3. 如何: <元素>{{变量名}}</元素>
4. 结果:
(1). 开局, new Vue()扫描到这里时,就会将这个元素保存到虚拟DOM树中
(2). 当{{}}中的变量在new Vue()中被修改时,虚拟DOM树就会找到这个元素,自动更新这个元素的内容与new Vue()同名变量保持一致!
5. 混搭: 其实在一个元素的内容中, {{变量名}}可以和其他字符串内容混搭。
6. {{}}之中: 和模板字符串的${}规则一样
(1). 可以写: 变量, 运算, 三目, 调用函数, 创建对象, 访问数组元素——一切合法的有返回值的js表达式
(2). 不能写: 程序结构(分支和循环), 以及没有返回值的js表达式。
7. 示例: 使用绑定语法绑定多种内容:
2_{{}}.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<h3>用户名:{{uname}}</h3>
<h3>性别:{{sex==1?"男":"女"}}</h3>
<h3>单价:¥{{price.toFixed(2)}}</h3>
<h3>数量:{{count}}</h3>
<h3>=========================</h3>
<h3>小计:¥{{(price*count).toFixed(2)}}</h3>
<h3>下单时间: {{new Date(orderTime).toLocaleString()}}</h3>
<h3>今天星期{{week[new Date().getDay()]}}</h3>
</div>
<script>
new Vue({
el:"#app",
data:{
uname:"dingding",
sex:1,
price:12.5,
count:5,
orderTime:1603425148601,
week:["日","一","二","三","四","五","六"]
}
})
</script>
</body>
</html>
运行结果:
用户名:dingding
性别:男
单价:¥12.50
数量:5
=========================
小计:¥62.50
下单时间: 2020/10/23 上午11:52:28
今天星期五
二. 指令(directive)
◼️ 什么是指令
专门在HTML中也能实现分支、循环等程序功能的特殊的自定义属性
◼️ 包括: 13种
1. v-bind
(1). 问题: 如果希望元素的属性值也随程序自动变化,如果使用{{}},会报错!——{{}}只支持元素内容变化,不支持属性值变化
(2). 解决: 今后只要希望元素的属性值随程序自动变化,都要用v-bind或:代替{{}}
(3). 如何:
a. 标准写法: <元素 v-bind:属性名="变量或js表达式">
b. 简写: <元素 :属性名="变量或js表达式">
(4). 结果: 当开局, new Vue()只要扫描到:属性名="变量或js表达式"语法,都会先执行""中的变量或js表达式,获得一个结果值。然后,再自动将结果值,设置为当前属性的属性值!
(5). 强调: 绑定属性值时,不要加{{}}了!一旦一个属性前加了:,则=后的"",其实就起到了{{}}等效的作用!
(6). 示例: 根据pm25的数值,动态显示不同表情图片
3_v-bind.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="js/vue.js"></script>
</head>
<body>
<!--1. 做界面
1.1 找可能发生变化的地方
//本例中: img的src属性可能发生变化,
//希望pm25<100,就显示img/1.png
//如果pm25<200,就显示img/2.png
//如果pm25<300,就显示img/3.png
//否则其余都显示img/4.png
-->
<div id="app">
<h3>今日空气质量:<img :src="pm25<100?'img/1.png':pm25<200?'img/2.png':pm25<300?'img/3.png':'img/4.png'"></h3>
<h3>{{pm25<100?'img/1.png':pm25<200?'img/2.png':pm25<300?'img/3.png':'img/4.png'}}</h3>
</div>
<script>
//2. 创建new Vue()对象
new Vue({
el:"#app",
//3. 创建模型对象
data:{
pm25:367
}
})
</script>
</body>
</html>
运行结果:
2. v-show
(1). 什么是: 专门控制一个元素显示隐藏的特殊指令
(2). 何时: 今后只要想控制一个元素显示隐藏都用v-show
(3). 如何: <元素 v-show="bool类型变量或js表达式">
(4). 结果: 每当new Vue()扫描到v-show时,都会先计算""中的变量值或js表达式的值:
a. 如果=右边的变量值或表达式结果为true,则当前元素什么也不做,默认正常显示
b. 如果=右边的变量值或表达式结果为false,则new Vue()自动给当前元素加上display:none,当前元素隐藏
(5). 示例: 实现打开关闭对话框
4_v-show.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="js/vue.js"></script>
<style>
.pop {
/* 以下6行代码是做一个相对于浏览器窗口居中的对话框的方法 */
width: 300px;
height: 150px;
position: fixed;
/* 让div上边框距离浏览器页面窗口50%,而非div这个元素 */
top: 50%;
/* 让div左边框距离浏览器页面窗口50%,而非div这个元素 */
left: 50%;
/* 宽的一半 */
/* margin-left:-150px; */
/* 高的的一半 */
/* margin-top:-75px; */
background-color: lightGreen;
color: green;
text-align: center;
}
.pop > .close {
float: right;
padding: 5px 10px;
cursor: pointer;
}
</style>
</head>
<body>
<!--1. 做界面
1.1 找界面中哪里可能发生变化:
本例中: 只有div.pop会发生变化。只有两种变化: 显示和隐藏
所以,非常适合用v-show来控制
1.2 找触发事件的元素
本例中:
当单击button时,打开对话框
当单击span时,关闭对话框
-->
<div id="app">
<button @click="open">登录</button>
<div v-show="show" class="pop">
<span @click="close" class="close">×</span>
<h1>登录成功!</h1>
</div>
</div>
<script>
//2. 创建new Vue对象
new Vue({
el: "#app",
//3. 创建模型对象
//3.1 创建data对象保存界面中所需的所有变量
//本例中: 界面里只需要1个变量
data: {
show: false, //开局,对话框默认应该是关闭的
},
//3.2 定义methods对象,保存界面中所需的所有函数
//本例中: 需要2个函数
methods: {
open() {
//设置当前对话框为打开
this.show = true;
},
close() {
//设置当前对话框为关闭
this.show = false;
},
},
});
</script>
</body>
</html>
运行结果:
3. v-if和v-else
(1). 问题:如果两个元素都要控制显示隐藏,而且根据同一个条件二选一显示隐藏。如果用v-show做,被迫把条件写2遍!
(2). 解决: 今后,只要控制2个元素二选一显示,都用v-if和v-else
(3). 如何:
<元素1 v-if="判断条件">
<元素2 v-else>
强调:
a. v-if和v-else所在的两个元素必须连着写!中间不能插入任何其他元素!
b. v-else后一定不要写条件!
(4). 原理: 每当new Vue()扫描到v-if时,会先执行=右边的判断条件:
a. 如果判断条件为true,则保留v-if所在的元素,删除v-else所在的元素
b. 如果判断条件为false,则删除v-if所在的元素,保留v-else所在的元素
v-show vs v-if 差别: 高频面试题
a. v-show 用display:none隐藏元素
b. v-if v-else 用删除元素方式隐藏元素
(6). 问题: v-if或v-else被删除的元素,怎么又重新回到页面的.
答: 虽然DOM树中的元素被删除了,但是虚拟DOM树中的元素,没有被删除。
(7). 示例: 切换用户登录和注销状态
5_v-if_v-else.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="js/vue.js"></script>
</head>
<body>
<!--1. 先做界面
1.1 找界面中哪里可能发生变化:
//本例中: 两个div都会显示隐藏变化
//多考虑一步: 因为两个div的显示隐藏只是靠用户是否登录这一个状态来控制的。无非判断条件是相反的。所以,只需要一个变量即可!
1.2 找触发事件的元素
//本例中: 登录按钮和注销按钮会触发事件
//点击登录,用户改为已登录状态
//点击注销,用户改为未登录状态
-->
<div id="app">
<!--第一个div是已登录时显示的内容-->
<div v-if="isLogin==true">
<h3>
Welcome, dingding | <a href="javascript:;" @click="logout">注销</a>
</h3>
</div>
<!--第二个div是未登录时显示的内容-->
<div v-else>
<a href="javascript:;" @click="login">登录</a> |
<a href="javascript:;">注册</a>
</div>
</div>
<script>
//2. 创建new Vue()对象
new Vue({
el: "#app",
//3. 创建模型对象:
//3.1 创建data对象,保存界面中需要的所有变量
//本例中: 只需要一个变量isLogin,用来表示用户是否登录
data: {
isLogin: false, //开局,默认用户是未登录
},
//3.2 创建methods对象,保存界面中需要的所有函数
//本例中: 需要两个函数,所以
methods: {
login() {
//让用户变成已登录状态
this.isLogin = true;
},
logout() {
this.isLogin = false;
},
},
});
</script>
</body>
</html>
运行结果:
🌱 扩展:Vue.js条件判断(v-if 和 v-show)
👉 v-if和v-else
v-if 可以配合v-else使用,也可以单独使用 。当配合v-else使用时,加有v-else的标签要紧跟加有v-if的标签之后,中间如果穿插其他标签,v-else将永远不会显示出来,并会报错!
如果v-if后面跟的是布尔值,而非变量语句的时候,可以根据布尔值真假判断显示和不显示 ,舍弃v-else 用v-if="flag" 配合 v-if="!flag"来解决中间不可以穿插其他标签的问题,可见v-if 配合v-else使用非常有局限性!
👉 v-if和v-show的区别
v-if底层控制的是节点的添加和删除,v-if一旦为假,带有v-if 的标签将不复存在,而v-show底层控制的是标签样式的显示和隐藏,并不会删除标签节点!
4. v-else-if
(1). 何时: 今后只要多个元素, 多选一显示隐藏,就可用v-else-if和v-if、v-else配合实现
(2). 如何:
<元素1 v-if="条件1">
<元素2 v-else-if="条件2">
... ...
<元素n v-else>
a. v-if、v-else-if和 v-else所在的多个元素必须连着写!中间不能插入任何其他元素!
b. v-else后一定不要写条件!
(3). 原理:
a. 每当new Vue()扫描到v-if时,会先执行=右边的判断条件。如果判断条件为true,则保留v-if所在的元素,删除除v-if之外的其余元素
b. 如果判断条件为false,则继续向后判断后续v-else-if后的条件。如果任意一个v-else-if的条件为true,则保留这个v-else-if所在的元素,删除其余元素
c. 如果所有v-if和v-else-if的条件都不满足,则只保留v-else所在的元素,删除其余元素。
(4). 示例: 根据pm25数值,显示不同表情
6_v-else-if.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="js/vue.js"></script>
</head>
<body>
<!--1. 做界面
1.1 找可能发生变化的地方
//本例中: 四个img元素的显示隐藏会发生变化。但是,因为四个img元素的显示隐藏都参照一个指标——pm25数值。所以,只需要1个变量即可!
-->
<div id="app">
<h3>
今日空气质量:
<img v-if="pm25<100" src="img/1.png" />
<img v-else-if="pm25<200" src="img/2.png" />
<img v-else-if="pm25<300" src="img/3.png" />
<img v-else src="img/4.png" />
</h3>
</div>
<script>
//2. 创建new Vue()对象
new Vue({
el: "#app",
//3. 创建模型对象
data: {
pm25: 367,
},
});
</script>
</body>
</html>
运行结果:
5. v-for
(1). 什么是: 专门反复生成多个相同结构的元素的特殊指令。
(2). 何时: 今后只要在网页上,反复生成多个相同结构,但是内容不同的一组元素时,都用v-for
(3). 如何:
:key="i">
(4). 原理:
a. 当new Vue()扫描到v-for时,先遍历of后的数组中每个元素
b. 每遍历一个数组元素,就会自动创建当前元素的一个副本。
c. 每次遍历时,都会取出当前数组元素值和当前下标位置,保存到of前的两个变量中:
1). of前的第一个变量,自动接住当前元素值
2). of前的第二个变量,自动接住当前下标位置
d. of前的两个变量,在当前元素范围内,可用于绑定语法或指令中,动态生成内容!
e. 坑: Vue中禁止使用下标,修改数组中的元素值。
原因: 数组的下标是数字,Vue只能监控自定义名称的属性,无法监控数字下标!
解决: 今后只要修改数组的内容,都必须用数组API修改。因为数组的所有API都是受到vue监控的。
比如: vm.数组[i]=新值 错误!页面不会改变
vm.数组.splice(i,1,新值) 正确
// 先删除i位置的一个旧元素,再在i位置添加一个新元素——替换
//复习第一阶段的数组函数
f. 问题: v-for反复创建的多个元素,除了内容不同之外,默认没有任何差别!如果我们用程序修改了数组中某一个元素时,v-for不知道该对应修改哪个元素副本。于是,就会采用最笨的方法——删除所有旧元素,重新遍历整个数组,并重建整个列表。——效率极低
:key="i"属性。
h. 结果:
1). 从此,v-for生成的每个元素副本身上,都多了一个唯一的标识key。值是不重复的。
2). 修改数组中任何一个元素值时,都只需要通过下标,找到这个元素值对应位置的DOM元素副本,只修改一个元素即可。不用重建整个列表。——效率高
7_v-for.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<ul>
<li v-for="(n,i) of names" :key="i">{{i+1}} - {{n}}</li>
</ul>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
names: ["亮亮", "然然", "东东", "嘻嘻"],
},
});
</script>
</body>
</html>
运行结果:
高频面试题:👇
强调:为什么必须加:key="i"?给每个元素副本添加唯一标识。修改数组中某个元素值时,避免重建整个列表,只需要修改一个DOM元素副本即可!提高修改效率。也就是说为了增加唯一标识、避免重建列表、只修改受影响的一个元素,所以更新效率高
i. 其实: v-for不但可以遍历数组,还可以遍历对象,类数组对象等等——看小程序视频
j. 其实: v-for还会数数:
<元素 v-for="i of 整数">
k. 原理: v-for会从1开始,数数,每次递增1,直到给定的整数位置。每数一个数,就会自动创建一个元素的副本。
8_v-for2.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="js/vue.js"></script>
<style>
/* ul{
list-style:none
}
ul>li{
float:left;
padding:5px 10px;
border:1px solid #555;
}
ul>li:first-child{
border-radius:3px 0 0 3px;
}
ul>li:last-child{
border-radius:0 3px 3px 0;
}
ul>li~li{
border-left:0;
}
ul>li:hover{
background-color:lightskyblue;
cursor:pointer;
} */
</style>
</head>
<body>
<div id="app">
<ul>
<li v-for="i of pageCount" :key="i">{{i}}</li>
</ul>
</div>
<script>
new Vue({
el: "#app",
data: {
//假设服务器端只给我返回了一个总页数
//需要在页面上动态生成相同个数的分页按钮
pageCount: 10,
},
});
</script>
</body>
</html>
运行结果: