本文版权归 “公众号 | 前端一万小时” 所有,欢迎转载!
转载请注明出处,未经同意,不可修改文章内容。
🔥🔥🔥本系列文章已在“公众号 | 前端一万小时”更新完毕,有需要的小伙伴可按需前往查看。
🔥🔥🔥“前端一万小时”两大明星专栏——“从零基础到轻松就业”、“前端面试刷题”,已于本月大改版,合二为一,干货满满,欢迎点击公众号菜单栏各模块了解。
涉及面试题:
1. v-show 和 v-if 指令的共同点和不同点?
2. v-if 和 v-for 的优先级?
3. 条件指令是什么?
[编号:vue_12]
🚀需求:在页面上显示 hello, qdywxs.
这个内容,可控制内容在页面上隐藏/显示。
1 v-if
和 v-show
指令
1.1 v-if
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>前端一万小时-Vue 中的条件渲染</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app">
<div v-if="show">
{{message}}
</div> <!-- 2️⃣在模板中添加一个 div 标签,内容为 message 的内容; -->
<!-- 3️⃣在 div 标签上添加一个 v-if 指令;(v-if 指令后面的内容依然是一个 JS 表达式,
表达式的值的真假,决定此 div 是否真实挂载在页面上,即内容显示与否); -->
<!-- 4️⃣-②:让 v-if 后面的表达式对应的变量为 show。 -->
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'hello, qdywxs.', // 1️⃣定义一个 message 数据,其内容为“hello, qdywxs.”;
// 4️⃣添加变量 show;
show: true // 4️⃣-①:data 中定义 show,默认为 true;
}
})
</script>
</body>
</html>
保存后返回页面,打开控制台通过改变 show
的真假来切换隐藏或显示:
1.2 v-show
v-show
指令与 v-if
类似:
<div id="app">
<div v-if="show">{{message}}</div>
<div v-show="show">{{message}}</div> <!-- ❗️新增一个 div,把 v-if 改为 v-show 指令! -->
</div>
保存后,页面上会出现两个 hello, qdywxs.
。我们通过更改 show
的真假,可以看到它们都会根据 show
的值来显示或隐藏:
1.3 v-if
🆚v-show
❓ v-if
和 v-show
的效果都一样,那它们之间有什么区别吗?
答:它们俩之间有一个明显的区别,我们可以直接测试一下。
<div id="app">
<!-- ❗️给两个 div 分别添加一个属性,以区别 v-if 和 v-show! -->
<div v-if="show" data-test="v-if">{{message}}</div>
<div v-show="show" data-test="v-show">{{message}}</div>
</div>
保存后返回页面,打开控制台并选中 div 元素查看效果:
当 show
的值为 true
时,页面上展示内容,且 v-if
和 v-show
都在 DOM 结构中:
当我们更改 show
的值为 false
后,页面上没有显示内容,但控制台可以看到:
v-show
的 div 依然还在页面上,只是多出一个 style 属性,display: none;
;v-if
没有被渲染在页面,不在 DOM 结构中。
v-if
和 v-show
都能控制元素是否在页面显示。
它们的区别是:
v-if
对应的表达式的值是 false 时,它所在标签不存在于 DOM 中,当值为 true 时重新添加入 DOM中;v-show
对应的表达式的值是 false 时,它所在标签依然存在 DOM 中,只是改变了元素的display
CSS 属性为 none。
即:v-if
通过对 DOM 移除或添加来隐藏/显示元素, v-show
通过改变元素的 display
属性来隐藏/显示元素。
所以当我们需要频繁的让一个 DOM 元素隐藏或显示时,使用 v-show
性能会更佳。
2 v-if
更复杂的使用方式
前置知识:《JavaScript 初识——④ 流程控制语句》
2.1 v-else
与 JS 中的条件控制语句 if
可以跟 else
连用类似, v-if
指令也可以与 v-else
连用:
<div id="app">
<!-- ❗️清除多余代码! -->
<div v-if="show">{{message}}</div> <!-- 1️⃣当 v-if 为 true 时,显示 message 的内容; -->
<!-- 2️⃣添加 v-else 指令; -->
<div v-else>I'm coming.</div> <!-- 2️⃣-①:新增一个 div,直接写 v-else 指令,不需要其他变量;
2️⃣-②:当 v-if 的值为 false 时,显示“I'm coming.”。 -->
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'hello, qdywxs.',
show: true
}
})
</script>
2.2 v-else-if
同理,Vue 中还有 v-else-if
,可以进行链式调用。
<div id="app">
<div v-if="show === 'a'">I'm A.</div> <!-- 1️⃣v-if 后面改为 show 是否等于 a; -->
<!-- 2️⃣添加两个 v-else-if 指令; -->
<div v-else-if="show === 'b'">I'm B.</div> <!-- 2️⃣-①:使用 v-else-if 指令,
表达式写 show 是否等于 b; -->
<div v-else-if="show === 'c'">I'm C.</div> <!-- 2️⃣-②:使用 v-else-if 指令,
表达式写 show 是否等于 c; -->
<div v-else>I'm not A/B/C.</div> <!-- 3️⃣最后一个写 v-else 指令; -->
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
show: 'a' // 4️⃣show 的默认值为 a。
}
})
</script>
当我们这样写的意思是:
show
的值是否为a
,如果是,显示I'm A.
;show
的值是否为b
,如果是,显示I'm B.
;show
的值是否为c
,如果是,显示I'm C.
;show
的值不是a
b
c
其中任何一个时 ,显示I'm not A/B/C.
。
保存后返回网页查看,由于 show
的默认值为 a
,所以第一次进入页面显示 I'm A.
。当 show
的值改变时,页面内容根据 show
的值进行改变:
❗️需要注意的是:v-if
、 v-else
和 v-else-if
之间都必须无其他标签插入。
我们以 v-if
和 v-else
为例:
<div id="app">
<div v-if="show === 'a'">I'm A.</div>
<span>test</span> <!-- ❗️添加一个 span! -->
<div v-else>I'm not A.</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
show: 'a'
}
})
</script>
如果它们之间有其他元素间隔,会直接报错:
3 v-if
与 key
值
❓v-if 与 key 值之间有什么关系?
要了解它们之间的关系,首先我们一起写这样一段代码来观察一下:
<div id="app">
<!-- 1️⃣添加 v-if 指令; -->
<div v-if="show">
用户名:<input> <!-- 1️⃣-①:添加一个用户名输入框;
1️⃣-②:使用 v-if 指令控制内容显示与否,当 show 为 true 时显示用户名输入框;
-->
</div>
<!-- 2️⃣添加 v-else 指令; -->
<div v-else>
邮箱名:<input> <!-- 2️⃣-①:添加一个邮箱名输入框;
2️⃣-②:使用 v-else 指令,当 show 为 false 时显示邮箱名输入框; -->
</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
show: true // 3️⃣show 默认值为 true。
}
})
</script>
保存返回页面可以看到,更改 show
值后好像并没有什么问题:
但当我们在输入框输入内容后,问题就出现了:输入用户名后再切换到邮箱名,输入的用户名也显示在邮箱名输入框中!
❓为什么会出现这样的现象?
答:这是因为 Vue 在重新渲染页面时,会尽量尝试复用页面上已经存在的 DOM。
比如我们的代码中,因为有两个 input
输入框。当在“用户名”中输入内容后切换到“邮箱名”时, Vue 会发现之前已经有一个 <input>
,所以它会尝试复用 <input>
。而 Vue 在复用了 <input>
框之后,并不会清空里面的内容。所以出现了这样的现象。
❓如何解决“复用”导致的问题?
答:可以通过添加 key
值的方式解决。
我们给两个 input
添加不同的 key
值:
<div id="app">
<div v-if="show">
用户名:<input key="username"> <!-- 1️⃣添加 key 值 username; -->
</div>
<div v-else>
邮箱名:<input key="email"> <!-- 2️⃣添加 key 值 email。 -->
</div>
</div>
❓为什么给元素添加 key
值后,Vue 就没有复用 DOM 了?
答:当给某个 DOM 元素添加 key
值时,Vue 就会知道它是页面上唯一的元素。如果两个元素的 key
值不同,那么 Vue 便不会尝试复用 DOM。
这是 Vue 中虚拟 DOM 的一个 diff 算法里用到的内容,理解起来相对会比较深,我们可以暂时不用了解太多。只需要记住:给某个 DOM 元素上加一个 key
值,Vue 会发现这个 key
值与别的 DOM 元素的 key
值不一样,Vue 就不会复用这部分的内容。
这样就可以避免刚才遇到的问题了。
祝好,qdywxs ♥ you!