跳到主要内容位置

Vue 3 使用 v-if/v-show 根据条件渲染页面内容

张旭乾

在前端开发中,除了需要经常展示列表内容外,还经常会根据一定条件展示页面内容,例如点击按钮的时候弹出对话框,当列表内容为空时,显示空白提示,或者在表单中展示验证错误等。那么在 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 入门到精通"],
};
},

结果:

v-if

这种情况下适合根据条件切换页面内容,并添加 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,所以展示了图书的列表。

v-if

如果我们回到 index.js 文件里,把 books 数组改成一个空数组:

data() {
return {
books: [],
};
},

就可以看到,它会显示『目前没有任何书籍』这段话。

v-if

如果我们保留一个元素在数组里边,例如"JavaScript 基础语法详解":

data() {
return {
books: ["JavaScript 基础语法详解"],
};
},
});

那么我们看一下结果,这里就会用 h2 显示了一本图书的标题。

v-if

再接下来,我们看一下 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 的数组再改成空的,看一下效果:

v-show

这个时候页面只显示了 p 元素的内容,不过我们在浏览器的开发者工具里看一下,右击页面空白处,点击审查元素,找到我们的 HTML 元素,可以看到 ul 元素 style 属性中的 display 样式,设置为了 none,它存在于 html 中,只是不可见。

v-show

如果我们把 books 数组改成长度大于 0 的:

books: ["JavaScript 基础语法详解", "Vue 入门实战", "React 入门到精通"],

再回到页面上,可以看到这次只展示了图书列表:

v-show

在开发者工具中可以看到,p 元素的 display 设置成了 none。

v-show

小结

这个就是在 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,在页面上不可见,适合添加过渡动画。

提示

一系列的课程让你成为高级前端工程师。课程覆盖工作中所有常用的知识点和背后的使用逻辑,示例全部都为工作项目简化而来,学完即可直接上手开发!

即使你已经是高级前端工程师,在课程里也可能会发现新的知识点和技巧,让你的工作更加轻松!

《React 完全指南》课程,连载中现只需 48 元(领取优惠券)点击查看详情。

《Vue 3.x 全家桶完全指南与实战》课程,包括 Vue 3.x、TypeScript、Vue Router 4.x、Vuex 4.x 所有初级到高级的语法特性详解,让你完全胜任 Vue 前端开发的工作。点击查看详情。

《React即时通信UI实战》课程,利用 Storybook、Styled-components、React-Spring 打造属于自己的组件库。

《JavaScript 基础语法详解》本人所著图书,包含 JavaScript 全面的语法知识和新特性, 可在京东、当当、淘宝等各大电商购买