# 条件渲染

# 介绍

这一节讲的是条件渲染,顾名思义,就是动态的让一个元素显示或者隐藏。主要由两个指令构成,分别是v-ifv-show。下面我们分别对着两个指令进行详细分析。

# v-if

v-if指令可以控制一个元素是否渲染。只有v-if的值为 truthy 后,才被渲染。关于 truthy 的解释可以查看这篇文档。其实简单的说就是为“真值”的时候才渲染。

还记得最开始的那个例子吗,让我们把它改变一下:

<template>
  <!-- change -->
  <div v-if="message">{{message}}</div>
  <!-- end -->
</template>

<script>
  export default {
    data() {
      return {
        message: 'Hello Vue!'
      }
    }
  }
</script>

<style></style>
Hello Vue!

上面代码标记出了改变的部分,我们使用v-if指令来控制<div>标签的显示或隐藏。v-if="message"表示,当message为 truthy 时,<div>标签显示,否则隐藏。

所以,变量message的值为: hello Vue!,转换后为真值,所以,这个<div>标签能够显示出来。

如果我们给值取个反呢?来看看,我们使用!进行取反操作:

<template>
  <!-- change -->
  <div v-if="!message">{{message}}</div>
  <!-- end -->
</template>

为了简化篇幅,没有改动的部分不做展示。 我们进行了取反操作后,果然,页面上原本的hello Vue!不见了。


vue 还提供了v-else。当v-if为“假值”时,显示此元素。就跟 JavaScript 的if/else一样。

<!-- 根据页面只能有一个根元素的原则,这里改变一下结构 -->
<div>
  <h1 v-if="!message">{{message}}</h1>
  <h1 v-else>Message 被隐藏了</h1>
</div>
Message 被隐藏了

通过上面例子可以看出,设置v-else的元素作为补充元素被显示出来。同时需要注意,v-else不需要提供任何值,同时只能作为v-if的补充。

v-else 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别。

如果你想要在添加另外一个条件呢? vue 又提供了v-else-if,用来充当v-if的下一个判断条件:

<template>
  <div>
    <h1 v-if="count < 0">count 小于0</h1>
    <h1 v-else-if="count == 0">count 等于0</h1>
    <h1 v-else>count 大于0</h1>

    <input type="number" v-model="count" />
  </div>
</template>

<script>
  export default {
    data() {
      return {
        count: 0
      }
    }
  }
</script>

count 等于0

这里为了更直观的展示v-else-if的效果,更换了一下例子中的值,把变量message更换为count,同时,分别把 count 与 0 进行了三次比较,显示比较后为 truthy 的元素。

为了展示 vue 中的双向绑定,在下方添加了一个<input>,并设置另外一个指令v-model。现在你不需要搞懂v-model的意思,只需感受一下效果即可,试着修改一下 input 中的值。

注意

在上例中<h1 v-else-if="count==0">count 等于0</h1> 进行比较时使用了==。相信大家应该知道=====的区别。为了保证一致性推荐大家使用===。本例使用==是因为<input>输出的值为字符串,所以为了更直观的展示而使用==进行比较。

# v-show

v-show指令跟v-if指令一样,都是用来条件渲染元素。不过v-show没有v-else,只能单一的判断条件。而且v-showv-if的渲染方式也有些区别,我们把上例进行如下修改:

<h1 v-show="count < 0">count 小于0</h1>
<h1 v-show="count == 0">count 等于0</h1>
<h1 v-show="count > 0">count 大于0</h1>

首先我们先把每个判断条件都改为v-show,然后把最后一个判断条件改为count > 0,因为v-show不支持v-else,只有v-if才能写v-else

count 小于0

count 等于0

count 大于0

进行了如上修改后,大家可能发现在效果上这两个例子看起来没有什么区别。但是实际上有很大的区别,大家可以打开 F12 控制台,然后选择Elements选项,观察<h1>标签的显示和隐藏。

<template>
  <div>
    <h1 v-if="count1 < 0">count1 小于0</h1>
    <h1 v-else-if="count1==0">count1 等于0</h1>
    <h1 v-else>count1 大于0</h1>

    <input type="number" v-model="count1" />

    <h1 v-show="count2 < 0">count2 小于0</h1>
    <h1 v-show="count2==0">count2 等于0</h1>
    <h1 v-show="count2 > 0">count2 大于0</h1>

    <input type="number" v-model="count2" />
  </div>
</template>

<script>
  export default {
    data() {
      return {
        count1: 0,
        count2: 0
      }
    }
  }
</script>

<style></style>

count1 等于0

count2 小于0

count2 等于0

count2 大于0

对应的控制台 Elements 选项卡页面显示应该如下

<div>
  <h1>count1 等于0</h1>
  <input type="number" />
  <h1 style="display: none;">count2 小于0</h1>
  <h1>count2 等于0</h1>
  <h1 style="display: none;">count2 大于0</h1>
  <input type="number" />
</div>

从上面可以看出,v-if指令控制的选项,为“假值”的元素并没有在页面上显示出来。而v-show为“假值”的元素是通过css属性display: none进行隐藏的。

不同的是带有 v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS 属性 display。

所以总的来说就是,v-if如果为“真值”的情况下,才会被渲染在页面上,而v-show则是不管什么情况下,都会渲染,只不过会通过 css 来进行隐藏

那么引申出来的就是性能问题。现在大家思考一下上面的例子,是使用v-if比较好呢,还是使用v-show比较好呢?答案是:使用v-show比较好。

因为我们在一个表单里面可以随意的输入任意数值,而只要输入的数值等于 0 或小于 0,对应的<h1>标签就需要从新计算,v-show只需要简单的切换一下 css 属性就可以切换了。而如果使用v-if的话,就需要重新渲染元素了。

一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

# 小例子

# 根据用户信息来给用户展示不同的界面

一般来说,在一个前后端分离的项目中,前端负责接收后端传过来的数据,然后展示页面。在 Vue 中,一般都是使用axios来发送 http 请求。我们接收到数据后,进行渲染。(在最后会提及axios的使用)

假设有一个会员中心页面,只有当用户为会员时,才展示对应的用户信息,否则展示申请会员界面。

<template>
  <div class="container">
    <!-- 会员展示用户信息 -->
    <div class="member">
      <p>姓名: {{userInfo.name}}</p>
      <p>年龄: {{userInfo.age}}</p>
      <p>性别: {{userInfo.sex === 1 ? '男' : '女'}}</p>
    </div>

    <!-- 非会员展示申请页面 -->
    <div class="noMember">
      <h1>你现在不是会员哦!</h1>
      <button>点击申请</button>
    </div>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        userInfo: {
          name: 'tim',
          age: 10,
          sex: 1, // 1 男 2 女
          isMember: 0 // 0 为非会员 1 为会员
        }
      }
    }
  }
</script>

<style scoped></style>

我们进行如上初始化,data里面的userInfo就是我们请求到的数据,一般我们都会使用1或2等 数字来表示是或否,比如说,性别sex,我们不会接收为sex: '男',只会接收到sex: 1这样的形式。

当我们请求到数据并写好页面后,就轮到判断是否是会员了。大家想一下,在页面初始化的时候,我们获取数据,接着进行判断,最后页面进行相对应的渲染。渲染一次之后,页面不会再切换了,只会展示一次,要么你是会员,就显示会员信息,要么你不是会员,则显示申请会员。 这么分析后,大家应该知道我们是使用v-if还是v-show了吧,我们把剩下的补上。

<template>
  <div class="container">
    <div v-if="userInfo.isMember" class="member">
      <p>姓名: {{userInfo.name}}</p>
      <p>年龄: {{userInfo.age}}</p>
      <p>性别: {{userInfo.sex === 1 ? '男' : '女'}}</p>
    </div>
    <div v-else class="noMember">
      <h1>你现在不是会员哦!</h1>
      <button>点击申请</button>
    </div>
  </div>
</template>

我们选择使用v-if进行判断,因为不在需要频繁的切换状态。这里有一点需要说明一下,v-if="userInfo.isMember"进行了简写,实际上为v-if="userInfo.isMember === 1"

提示

在 JavaScript 中,truthy(真值)指的是在布尔值上下文中,转换后的值为真的值。所有值都是真值,除非它们被定义为 假值(即除 false、0、""、null、undefined 和 NaN 以外皆为真值)。

那我们换个思路来想,if(1)返回trueif(0)返回false。所以v-if="userInfo.isMember"会自动判断,如果为1就显示,为0就隐藏,最终表达式返回0 ,则显示会员申请页面。

这里还有一点没有提及,就是模板语法可以使用表达式,因为官网有提及,比较简单,就没有细说。上例我们使用三元表达式 进行判断,如果为1说明性别为男,我们就展示为男,否则展示为女。

目前为止,我们已经学会了根据用户信息,来判断展示不同的界面。 我们在拓展一下,展示一下 Vue 自动更新数据的魅力。在上例的基础上,给申请按钮添加一个真实的点击事件:

<button @click="userInfo.isMember = 1">点击申请</button>

我们把申请按钮进行如下修改,现在你看不懂没关系,下面我们会介绍。我们只是简单的设置一个 click 事件,点击后把isMember的值设置为 1。

注意

这里为了展示效果,只是在data里面把值改变了,在真实的项目是需要发送http请求!

你现在不是会员哦!

现在,点击 点击申请 按钮后, 页面会马上展示 会员的界面,同时把申请界面进行隐藏。这里面的工作全是 Vue 在“背后”进行的,我们只需要改变一下对应的值即可。


返回上一页

上次更新: 2/3/2020, 9:47:35 PM