条件渲染
v-if
v-if
指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回真值时才被渲染。
<h1 v-if="awesome">Vue is awesome!</h1>
v-else
你也可以使用 v-else
为 v-if
添加一个“else 区块”。
<button @click="awesome = !awesome">Toggle</button>
<h1 v-if="awesome">Vue is awesome!</h1>
<h1 v-else>Oh no 😢</h1>
一个 v-else
元素必须跟在一个 v-if
或者 v-else-if
元素后面,否则它将不会被识别。
v-else-if
顾名思义,v-else-if
提供的是相应于 v-if
的 else if
区块。它可以连续多次重复使用:
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
和 v-else
类似,一个使用 v-else-if
的元素必须紧跟在一个 v-if
或一个 v-else-if
元素后面。
<template>
上的 v-if
因为 v-if
是一个指令,他必须依附于某个元素。但如果我们想要切换不止一个元素呢?在这种情况下我们可以在一个 <vue>
元素上使用 v-if
,这只是一个不可见的包装器元素,最后渲染的结果并不会包含这个 <vue>
元素。
<template v-if="ok">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
v-else
和 v-else-if
也可以在 <template>
上使用。
v-show
另一个可以用来按条件显示一个元素的指令是 v-show
。其用法基本一样:
<h1 v-show="ok">Hello!</h1>
不同之处在于 v-show
会在 DOM 渲染中保留该元素;v-show
仅切换了该元素上名为 display
的 CSS 属性。
v-show
不支持在 <vue>
元素上使用,也不能和 v-else
搭配使用。
v-if
vs. v-show
v-if
是“真实的”按条件渲染,因为它确保了在切换时,条件区块内的事件监听器和子组件都会被销毁与重建。
v-if
也是惰性的:如果在初次渲染时条件值为 false,则不会做任何事。条件区块只有当条件首次变为 true 时才被渲染。
相比之下,v-show
简单许多,元素无论初始条件如何,始终会被渲染,只有 CSS display
属性会被切换。
总的来说,v-if
有更高的切换开销,而 v-show
有更高的初始渲染开销。因此,如果需要频繁切换,则使用 v-show
较好;如果在运行时绑定条件很少改变,则 v-if
会更合适。
案例
v-show 和 v-if 条件渲染
目标:控制标签的隐藏或出现
- 语法:
- v-show="vue 变量"
- v-if="vue 变量"
- 原理
- v-show 用的 display:none 隐藏 (频繁切换使用)
- v-if 直接从 DOM 树上移除
- 高级
- v-else 使用
<script setup>
import { ref } from "vue";
const is_ok = ref(true);
const age = ref(15);
</script>
<vue>
<div>
<!-- v-show 或者 v-if
v-show="vue 变量"
v-if="vue 变量"
-->
<h1 v-show="is_ok">v-show 的盒子</h1>
<h1 v-if="is_ok">v-if 的盒子</h1>
<!--
v-show 隐藏:采用 display:none // 频繁切换
v-if 隐藏:采用从 DOM 树直接移除 // 移除
-->
<div>
<!-- v-if 和 v-else 使用 -->
<p v-if="age > 18">我成年了</p>
<p v-else>还得多吃饭</p>
</div>
</div>
</vue>
<style scoped></style>
总结:使用 v-show 和 v-if 以及 v-else 指令,方便通过变量控制一套标签出现/隐藏
案例 - 折叠面板
目标:点击展开或收起时,把内容区域显示或者隐藏
参考 bootstrap5 折叠面板 ,只需要完成一个元素的展开与收起即可。
此案例使用了 less 语法,项目中下载模块
# .less
npm install -D less
只有标签和样式
<script setup>
import { ref } from "vue";
const is_show = ref(true);
const btn = () => {
// 3. 点击时,把值改成 false
is_show.value = !is_show.value;
};
</script>
<vue>
<div>
<h3>案例:折叠面板</h3>
<div>
<div class="title">
<h4>芙蓉楼送辛渐</h4>
<!-- 1.绑定点击事件 -->
<span class="btn" @click="btn">
<!-- 4. 根据 isShow 的值显示不同文字 -->
{{ is_show ? '收起' : '展开' }}
</span>
</div>
<!-- 2. v-show 配合变量来控制标签隐藏出现 -->
<div class="container" v-show="is_show">
<p>寒雨连江夜入吴,</p>
<p>平明送客楚山孤。</p>
<p>洛阳亲友如相问,</p>
<p>一片冰心在玉壶。</p>
</div>
</div>
</div>
</vue>
<style scoped lang="less">
body {
background-color: #ccc;
#app {
width: 400px;
margin: 20px auto;
background-color: #fff;
border: 4px solid blueviolet;
border-radius: 1em;
box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.5);
padding: 1em 2em 2em;
h3 {
text-align: center;
}
.title {
display: flex;
justify-content: space-between;
align-items: center;
border: 1px solid #ccc;
padding: 0 1em;
}
.title h4 {
line-height: 2;
margin: 0;
}
.container {
border: 1px solid #ccc;
padding: 0 1em;
}
.btn {
/* 鼠标改成手的形状 */
cursor: pointer;
}
}
}
</style>