# 条件渲染
# 介绍
这一节讲的是条件渲染,顾名思义,就是动态的让一个元素显示或者隐藏。主要由两个指令构成,分别是v-if
和v-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>
上面代码标记出了改变的部分,我们使用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>
通过上面例子可以看出,设置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-show
和v-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)
返回true
,if(0)
返回false
。所以v-if="userInfo.isMember"
会自动判断,如果为1
就显示,为0
就隐藏,最终表达式返回0
,则显示会员申请页面。
这里还有一点没有提及,就是模板语法可以使用表达式,因为官网有提及,比较简单,就没有细说。上例我们使用三元表达式 进行判断,如果为1
说明性别为男,我们就展示为男,否则展示为女。
目前为止,我们已经学会了根据用户信息,来判断展示不同的界面。 我们在拓展一下,展示一下 Vue 自动更新数据的魅力。在上例的基础上,给申请按钮添加一个真实的点击事件:
<button @click="userInfo.isMember = 1">点击申请</button>
我们把申请按钮进行如下修改,现在你看不懂没关系,下面我们会介绍。我们只是简单的设置一个 click 事件,点击后把isMember
的值设置为 1。
注意
这里为了展示效果,只是在data
里面把值改变了,在真实的项目是需要发送http
请求!
你现在不是会员哦!
现在,点击 点击申请
按钮后, 页面会马上展示 会员的界面,同时把申请界面进行隐藏。这里面的工作全是 Vue 在“背后”进行的,我们只需要改变一下对应的值即可。