> 文章列表 > 七、vue-基础之条件渲染

七、vue-基础之条件渲染

七、vue-基础之条件渲染

一、条件渲染

在某些情况下,我们需要根据当前的条件决定某些元素或者组件是否渲染,这个时候我们就需要进行条件判断了。

Vue提供了下面的指令来进行条件判断:

  • v-if
  • v-else
  • v-else-if
  • v-show

(1)需求demo体验 

 我们直接来个demo~将names数组里的数据分别展示出来。

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><div id="app"><ul><li v-for="item in names">{{ item }}</li></ul></div><script src="../lib/vue.js"></script><script>const app = Vue.createApp({// data: option apidata: function () {return {names: ["abc", "cba", "nba"],}},})app.mount("#app")</script></body>
</html>

页面展示: 

那此时我们再补一个需求,希望names有数据的时候展示上面部分,names无数据的时候展示下面h2元素。

 我们直接上代码~ 很好理解吧。

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><!-- 模板语法里面 --><div id="app"><ul v-if="names.length > 0"><li v-for="item in names">{{ item }}</li></ul><h2 v-else>当前names没有数据,请求获取数据后展示</h2></div><script src="../lib/vue.js"></script><script>const app = Vue.createApp({// data: option apidata: function () {return {names: ["abc", "cba", "nba"],}},})app.mount("#app")</script></body>
</html>

 (2)v-if

我们来个栗子🌰~

如果info没有值,就不展示那一栏。否则前端只展示姓名: 年龄:是不是不友好。

有伙伴说简单,直接像下面这样子写:

很明显是不行的,如果info是{},空对象布尔值还是true,所以不能这么写。 

那该怎么去写呢?

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><div id="app"><!-- v-if="条件" --><div class="info" v-if="Object.keys(info).length"><h2>个人信息</h2><ul><li>姓名: {{ info.name }}</li><li>年龄: {{ info.age }}</li></ul></div></div><script src="../lib/vue.js"></script><script>const app = Vue.createApp({// data: option apidata() {return {info: { name: "daxia", age: 18 },}},})app.mount("#app")</script></body>
</html>

 有小伙伴也提出来了,如果info对象里面只有name 没有age呢?那前端页面是不是也不应该展示age这个字段。

我们可以再加个v-if。 

我们看下效果 

 实际工作中基本不会遇到这种情况,为啥?正常来说我们如果有这个对象,基本是用v-for去遍历。有就渲染 没有就不渲染。

(3)v-else

正常工作当中,我们不会像上面的案例一样,仅仅只是如果满足条件就展示,不满足就什么都不展示。实际工作中,我们会根据条件去判断渲染哪一个,如果条件不满足渲染另外一个。

v-if ,v-else搭配着使用。

(4)v-else-if

我们再来一个demo,当score分数达到90分是优秀,60<=score<90是良好,小于60分是不及格。

注意v-else-if可以用多个。

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><div id="app"><h2 v-if="score>=90">优秀</h2><!-- <h2 v-else-if="60<score<90">良好</h2> --><h2 v-else-if="score>60 && score<90">良好</h2><h2 v-else="score<60">不及格</h2></div><script src="../lib/vue.js"></script><script>const app = Vue.createApp({// data: option apidata() {return {score: 89,}},})app.mount("#app")</script></body>
</html>

(5) v-if的渲染原理

 v-if的渲染原理:

  • v-if是惰性的;
  • 当条件为false时,其判断的内容完全不会被渲染或者被销毁掉;
  • 当条件为true时,才会真正渲染条件块中的内容;

 啥意思呢?

我们看一个条件为false的场景,

我们看下前端页面长啥样子,当条件为false的时候,是不是连元素都没有。

 

(6)template元素

因为v-if是一个指令,所以必须将其添加到一个元素上:

  • 但是如果我们希望切换的是多个元素呢?
  • 此时我们渲染div,但是我们并不希望div这种元素被渲染;
  • 这个时候,我们可以选择使用template

template元素可以当做不可见的包裹元素,并且在v-if上使用,但是最终template不会被渲染出来:

  • 有点类似于小程序中的block

 我们看下这个案例,是不是2部分,条件成立的时候渲染上面那部分,条件不成立的时候渲染下面那部分,我们上下两部分里面,最核心的是不是两个里面的具体内容要不要渲染出来,那外面为什么要包裹一个div呢?这个div用的意义是将里面的内容包裹起来,当成一个整体。当成一个整体之后,我们可以对这个整体做一个判断。不然的话只能把条件挨个写在每一个内部的内容标签上面。

但是用了div包裹后,其实是存在一个弊端的。我们最外层的div其实对我们显示的效果来说,是没有存在的必要的。  这里我们把info设置为空对象,看下效果。这个div是不是对我们显示的效果来说,是没必要存在的。

从浏览器的性能来说,你多加一个元素是不是浏览器就要多创建一个元素对象。

那我们能不能把这个元素删掉呢?

 我们现在把外面包裹的div都删掉,那我们怎么把v-if、v-else条件应用在各自需要展示的元素上面呢?

在早期vue2的时候,这里是必须要包裹一个div的或者别的元素的。

但是现在在vue3,引入template元素,这个元素本身是没有特殊的含义的。他只是把整个的这一块逻辑包裹在一起,页面上不会去渲染这个元素。

他唯一的作用就是在这个元素上面增加一个指令。

我们附下使用使用template的代码:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><div id="app"><!-- v-if="条件" --><template v-if="Object.keys.length"><h2>个人信息</h2><ul><li>姓名: {{ info.name }}</li><li>年龄: {{ info.age }}</li></ul></template><!-- v-else --><template v-else><h2>没有输入个人信息</h2><p>请输入个人信息后再进行展示~</p></template></div><script src="../lib/vue.js"></script><script>const app = Vue.createApp({// data: option apidata() {return {info: {},}},})app.mount("#app")</script></body>
</html>

 我们看下页面效果,是不是没有额外加的div元素了对吧~ 

(7)条件渲染-阶段案例

我们来个案例:有个按钮和一个图片,我点击按钮图片消失,再点击一下按钮图片出现。

我们以前是怎么实现的?

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title><style>img {width: 200px;height: 200px;}</style></head><body><div id="app"><div><button @click="toggle">切换</button></div><template v-if="isShowCode"><img src="https://img1.baidu.com/it/u=666927474,3753237121&fm=253&fmt=auto&app=138&f=GIF?w=504&h=500" alt="" /></template></div><script src="../lib/vue.js"></script><script>const app = Vue.createApp({// data: option apidata() {return {isShowCode: true,}},methods: {toggle() {this.isShowCode = !this.isShowCode},},})app.mount("#app")</script></body>
</html>

(8) v-show

基于上面的案例,我们将代码改了一下template改成了div, v-if 改成了v-show。实现了界面相同的效果。

 


 我们来看下v-if 和v-show 本质具体是什么区别?

我们有2个div,分别是用v-if 和 v-show 。

需要展示的时候,两个是没什么区别。

如果不需要展示的时候,我们看下区别。v-show 是使用style = "display:none"将他隐藏起来了,本质是修改属性的操作。

但是v-if 如果不需要展示的话,元素就直接被销毁掉了,根本不会存在这个元素了。

了解到本质区别之后,我还有一个疑惑,

为什么v-show 不让用 template呢?

答:因为template这个元素压根不存在,但是当我为true的时候,我希望这个元素能够被渲染出来,而且当为false的时候,只是设置这个元素display:none。你压根就没这个元素,我怎么给你设置style?大家理解了嘛~