Vue 3 使用 v-if/v-show 根据条件渲染页面内容
2022年8月 · 预计阅读时间: 5 分钟
在前端开发中,除了需要经常展示列表内容外,还经常会根据一定条件展示页面内容,例如点击按钮的时候弹出对话框,当列表内容为空时,显示空白提示,或者在表单中展示验证错误等。那么在 Vue 3 中,我们使用 v-if 以及相关的 v-else-if 和 v-else 指令来实现条件判断,或者使用 v-show 指令。我们分别看一下它们的作用、使用方法和区别。
v-if、v-else-if 和 v-else
v-if、v-else-if 和 v-else 和 JavaScript 中的 if...else if...else 功能是一样的:
if (books.length === 0) {
} else if (books.length === 1) {
} else {
}
当满足 if 条件时,代码会走到 if 代码块,如果不满足,就会接着检查 else if 的条件是不是满足,如果满足就执行 else if 代码块,如果不满足,并且后面还有 else if,就会继续判断,如果后面是 else,则直接走到 else 语句块中。 vue 中的 v-if、v-else-if 和 v-else 执行逻辑是:
- 判断设置了 v-if 的 html 模板标签,它里边的条件是否满足。
- 如果满足则显示这个标签,不满足就不显示。
- 如果后面有 v-else-if 的标签,那么在 v-if 条件不满足时,会判断 v-else-if 中的条件。
- 如果 v-else-if 的条件满足的话,就显示这个标签的内容,如果不满足的话,并且后面还有 v-else-if,那么会继续判断,依次类推,如果后面是 v-else,那么会显示 v-else 所在标签的内容。
<p v-if="books.length === 0">目前没有任何书籍</p>
<h2 v-else-if="books.length === 1">{{ books[0] }}</h2>
<ul v-else>
<li v-for="book in books">{{ book }}</li>
</ul>
data() {
return {
books: ["JavaScript 基础语法详解", "Vue 入门实战", "React 入门到精通"],
};
},
这里的条件表达式和 JavaScript 中的一样:
- 要求结果返回真值(true、1、非空字符串等)
- 或假值(false、0、undefined、null、"" 等)
需要注意的是,带有 v-if、v-else-if 和 v-else 指令的标签必须紧挨着,才能让判断逻辑生效。 另外,v-else-if 和 v-else 也都可以省略。例如只有一个 v-if 的话,那么在判断完条件之后,如果满足就渲染这个标签,如果不满足,就继续渲染后续标签:
<p v-if="books.length === 0">目前没有任何书籍</p>
<ul>
<li v-for="book in books">{{ book }}</li>
</ul>
data() { return { books: ["JavaScript 基础语法详解", "Vue 入门实战", "React
入门到精通"], }; },
v-show
与 v-if 作用类似的,还有 v-show 指令。在使用 v-if 的时候,如果条件不满足,那么这个标签是不会在最终的 html 中渲染出来的,而使用 v-show,即使条件不满足,但 html 标签仍然会渲染出来,只是它的样式会设置为 display: none:
<p v-show="books.length === 0">目前没有任何书籍</p>
<ul v-show="books.length > 0">
<li v-for="book in books">{{ book }}</li>
</ul>
data() {
return {
books: ["JavaScript 基础语法详解", "Vue 入门实战", "React 入门到精通"],
};
},
结果:
这种情况下适合根据条件切换页面内容,并添加 CSS 动画过渡效果的情况,因为 CSS 过渡动画要求 HTML 元素必须都是已渲染出来的,这样 CSS 过渡属性才能生效。
示例
好,在介绍完 v-if、v-else-if 和 v-else 的概念之后,我们来看一下示例的实际运行效果。我们要根据一个图书数组的长度,来分别展示列表为空的情况、只有一本图书的情况和有多本图书的情况。 首先打开 index.js 文件,我们在 data() 函数返回的对象中,添加一个 books 属性,值为一个数组,里边写上一些示例图书的标题:
// 示例:根据条件展示页面内容
const app = Vue.createApp({
data() {
return {
books: ["JavaScript 基础语法详解", "Vue 入门实战", "React 入门到精通"],
};
},
});
app.mount("#app");
然后打开 index.html,我们使用一个 p 元素,显示一些提示文字,当图书的数组长度为 0 的时候显示。直接在 p 元素中,使用 v-if 指令,它的值是一个 JavaScript 表达式,判断 books.length 是不是等于 0,如果等于 0 就会显示 "目前没有任何书籍" 字样:
<p v-if="books.length === 0">目前没有任何书籍</p>
接着,判断,如果图书数组只有一个元素,那么就使用一个 h2 元素显示这本图书的标题,那么我们可以在 p 元素的下方,定义一个 h2 元素,使用 v-else-if 判断 books 数组的长度是否为 1,如果为 1,就展示数组里的第 0 个元素的内容,也就是数组里唯一的 1 一个元素:
<h2 v-else-if="books.length === 1">{{ books[0] }}</h2>
接着,如果是其它情况下,那么就使用 ul 展示图书列表,那么我们可以在 h2 的下方定义一个 ul,使用 v-else 指令,v-else 不需要条件,上边的条件不满足时,会自动走到 v-else 这里来:
<ul v-else>
<li v-for="book in books">{{ book }}</li>
</ul>
ul 中的 li 元素使用了上节课介绍的 v-for 循环来渲染多个图书。 好了,我们现在来预览一下,因为数组的长度为 3,所以展示了图书的列表。
如果我们回到 index.js 文件里,把 books 数组改成一个空数组:
data() {
return {
books: [],
};
},
就可以看到,它会显示『目前没有任何书籍』这段话。
如果我们保留一个元素在数组里边,例如"JavaScript 基础语法详解":
data() {
return {
books: ["JavaScript 基础语法详解"],
};
},
});
那么我们看一下结果,这里就会用 h2 显示了一本图书的标题。
再接下来,我们看一下 v-show 的效果,我们回到 index.html 中,把模板改一下:
- 把 p 元素的 v-if 改成 v-show
- 删除 h2 标签,我们这里先不用它了。
- 然后把 ul 元素的 v-else 也改成 v-show,判断 books 的长度是不是大于 0。
<p v-show="books.length === 0">目前没有任何书籍</p>
<ul v-show="books.length > 0">
<li v-for="book in books">{{ book }}</li>
</ul>
现在我们把 books 的数组再改成空的,看一下效果:
这个时候页面只显示了 p 元素的内容,不过我们在浏览器的开发者工具里看一下,右击页面空白处,点击审查元素,找到我们的 HTML 元素,可以看到 ul 元素 style 属性中的 display 样式,设置为了 none,它存在于 html 中,只是不可见。
如果我们把 books 数组改成长度大于 0 的:
books: ["JavaScript 基础语法详解", "Vue 入门实战", "React 入门到精通"],
再回到页面上,可以看到这次只展示了图书列表:
在开发者工具中可以看到,p 元素的 display 设置成了 none。
小结
这个就是在 vue 中根据条件展示不同页面内容的方法,主要是使用 v-if、v-else-if 和 v-else,它们的用法和 JavaScript 中的 if...else if...else 一样,只是使用这些指令的元素必须相邻,另外 v-else-if 和 v-else 也可以省略。另一种方式是使用 v-show,与 v-if 不同的是,v-show 在条件不满足的时候仍然会渲染标签,只是会把它的 display 属性设置为 none,在页面上不可见,适合添加过渡动画。