(12)Vue 入门——⑦ 条件渲染 | Vue 基础理论实操

2,339 阅读5分钟
本文版权归 “公众号 | 前端一万小时” 所有,欢迎转载!

转载请注明出处,未经同意,不可修改文章内容。

🔥🔥🔥本系列文章已在“公众号 | 前端一万小时”更新完毕,有需要的小伙伴可按需前往查看。

🔥🔥🔥“前端一万小时”两大明星专栏——“从零基础到轻松就业”、“前端面试刷题”,已于本月大改版,合二为一,干货满满,欢迎点击公众号菜单栏各模块了解。


涉及面试题:
1. v-show 和 v-if 指令的共同点和不同点?
2. v-if 和 v-for 的优先级?
3. 条件指令是什么?

[编号:vue_12]

🔗本阶段对应的“官方文档”阅读“条件渲染”章节


🚀需求:在页面上显示 hello, qdywxs. 这个内容,可控制内容在页面上隐藏/显示。 vue12-01.png

1 v-ifv-show 指令

1.1 v-if

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>前端一万小时-Vue 中的条件渲染</title>
  <script src="./vue.js"></script>
</head>
<body>
  <div id="app">

    <div v-if="show">
      {{message}}
    </div> <!-- 2️⃣在模板中添加一个 div 标签,内容为 message 的内容; -->

           <!-- 3️⃣在 div 标签上添加一个 v-if 指令;(v-if 指令后面的内容依然是一个 JS 表达式,
					 表达式的值的真假,决定此 div 是否真实挂载在页面上,即内容显示与否); -->

           <!-- 4️⃣-②:让 v-if 后面的表达式对应的变量为 show。 -->

  </div>

  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        
        message: 'hello, qdywxs.', // 1️⃣定义一个 message 数据,其内容为“hello, qdywxs.”;

        // 4️⃣添加变量 show;
        show: true // 4️⃣-①:data 中定义 show,默认为 true;
      }
    })
  </script>
</body>
</html>

保存后返回页面,打开控制台通过改变 show 的真假来切换隐藏或显示:

vue_12-02.gif

1.2 v-show

v-show 指令与 v-if 类似:

<div id="app">
  <div v-if="show">{{message}}</div>

  <div v-show="show">{{message}}</div> <!-- ❗️新增一个 div,把 v-if 改为 v-show 指令! -->

</div>

保存后,页面上会出现两个 hello, qdywxs. 。我们通过更改 show 的真假,可以看到它们都会根据 show 的值来显示或隐藏:

vue_12-03.gif

1.3 v-if 🆚v-show

v-if 和 v-show 的效果都一样,那它们之间有什么区别吗?

答:它们俩之间有一个明显的区别,我们可以直接测试一下。

<div id="app">

  <!-- ❗️给两个 div 分别添加一个属性,以区别 v-if 和 v-show! -->
  <div v-if="show" data-test="v-if">{{message}}</div>
  <div v-show="show" data-test="v-show">{{message}}</div>

</div>

保存后返回页面,打开控制台并选中 div 元素查看效果:

vue_12-04.gif

show 的值为 true 时,页面上展示内容,且 v-ifv-show 都在 DOM 结构中: vue12-05.png

当我们更改 show 的值为 false 后,页面上没有显示内容,但控制台可以看到:

  1. v-show 的 div 依然还在页面上,只是多出一个 style 属性, display: none;
  2. v-if 没有被渲染在页面,不在 DOM 结构中。

vue12-06.png

v-ifv-show 都能控制元素是否在页面显示。

它们的区别是:

  • v-if 对应的表达式的值是 false 时,它所在标签不存在于 DOM 中,当值为 true 时重新添加入 DOM中;
  • v-show 对应的表达式的值是 false 时,它所在标签依然存在 DOM 中,只是改变了元素的 display CSS 属性为 none。

即:v-if 通过对 DOM 移除或添加来隐藏/显示元素, v-show 通过改变元素的 display  属性来隐藏/显示元素。

所以当我们需要频繁的让一个 DOM 元素隐藏或显示时,使用 v-show 性能会更佳。

2  v-if 更复杂的使用方式

前置知识:《JavaScript 初识——④ 流程控制语句》

2.1 v-else

与 JS 中的条件控制语句 if 可以跟 else 连用类似, v-if 指令也可以与 v-else 连用:

<div id="app">

  <!-- ❗️清除多余代码! -->

  <div v-if="show">{{message}}</div> <!-- 1️⃣当 v-if 为 true 时,显示 message 的内容; -->

  <!-- 2️⃣添加 v-else 指令; -->
  <div v-else>I'm coming.</div> <!-- 2️⃣-①:新增一个 div,直接写 v-else 指令,不需要其他变量;
                                2️⃣-②:当 v-if 的值为 false 时,显示“I'm coming.”。 -->
</div>

<script>
  var vm = new Vue({
    el: '#app',
    data: {
      message: 'hello, qdywxs.',
      show: true
    }
  })
</script>

vue_12-07.gif

2.2  v-else-if

同理,Vue 中还有 v-else-if ,可以进行链式调用。

<div id="app">

  <div v-if="show === 'a'">I'm A.</div> <!-- 1️⃣v-if 后面改为 show 是否等于 a; -->

  <!-- 2️⃣添加两个 v-else-if 指令; -->
  <div v-else-if="show === 'b'">I'm B.</div> <!-- 2️⃣-①:使用 v-else-if 指令,
																						 表达式写 show 是否等于 b; -->

  <div v-else-if="show === 'c'">I'm C.</div> <!-- 2️⃣-②:使用 v-else-if 指令,
																						 表达式写 show 是否等于 c; -->

  <div v-else>I'm not A/B/C.</div> <!-- 3️⃣最后一个写 v-else 指令; -->
</div>

<script>
  var vm = new Vue({
    el: '#app',
    data: {

      show: 'a' // 4️⃣show 的默认值为 a。
    }
  })
</script>

当我们这样写的意思是:

  1. show 的值是否为 a ,如果是,显示 I'm A.
  2. show 的值是否为 b ,如果是,显示 I'm B.
  3. show 的值是否为 c ,如果是,显示 I'm C.
  4. show 的值不是 a b c 其中任何一个时 ,显示 I'm not A/B/C.

保存后返回网页查看,由于 show 的默认值为 a ,所以第一次进入页面显示 I'm A. 。当 show 的值改变时,页面内容根据 show 的值进行改变:

vue_12-08.gif

❗️需要注意的是:v-if 、 v-else 和 v-else-if 之间都必须无其他标签插入。 

 我们以 v-ifv-else 为例:

<div id="app">
  <div v-if="show === 'a'">I'm A.</div>

  <span>test</span> <!-- ❗️添加一个 span! -->

  <div v-else>I'm not A.</div>
</div>

<script>
  var vm = new Vue({
    el: '#app',
    data: {
      show: 'a'
    }
  })
</script>

如果它们之间有其他元素间隔,会直接报错: vue12-09.png

3 v-ifkey

❓v-if 与 key 值之间有什么关系?

要了解它们之间的关系,首先我们一起写这样一段代码来观察一下:

<div id="app">
	
  <!-- 1️⃣添加 v-if 指令; -->
  <div v-if="show">
    用户名:<input> <!-- 1️⃣-①:添加一个用户名输入框;
                   1️⃣-②:使用 v-if 指令控制内容显示与否,当 show 为 true 时显示用户名输入框;
									 -->
  </div>

  <!-- 2️⃣添加 v-else 指令; -->
  <div v-else>
    邮箱名:<input> <!-- 2️⃣-①:添加一个邮箱名输入框;
                   2️⃣-②:使用 v-else 指令,当 show 为 false 时显示邮箱名输入框; -->
  </div>

</div>

<script>
  var vm = new Vue({
    el: '#app',
    data: {

      show: true // 3️⃣show 默认值为 true。
    }
  })
</script>

保存返回页面可以看到,更改 show 值后好像并没有什么问题:

vue_12-10.gif

但当我们在输入框输入内容后,问题就出现了:输入用户名后再切换到邮箱名,输入的用户名也显示在邮箱名输入框中

vue_12-11.gif

❓为什么会出现这样的现象?

答:这是因为 Vue 在重新渲染页面时,会尽量尝试复用页面上已经存在的 DOM。

比如我们的代码中,因为有两个 input 输入框。当在“用户名”中输入内容后切换到“邮箱名”时, Vue 会发现之前已经有一个 <input> ,所以它会尝试复用 <input> 。而 Vue 在复用了 <input> 框之后,并不会清空里面的内容。所以出现了这样的现象。

❓如何解决“复用”导致的问题?

答:可以通过添加 key 值的方式解决。

我们给两个 input 添加不同的 key 值:

<div id="app">

  <div v-if="show">
    用户名:<input key="username"> <!-- 1️⃣添加 key 值 username; -->
  </div>

  <div v-else>
    邮箱名:<input key="email"> <!-- 2️⃣添加 key 值 email。 -->
  </div>

</div>

vue_12-12.gif

❓为什么给元素添加 key 值后,Vue 就没有复用 DOM 了?

答:当给某个 DOM 元素添加 key 值时,Vue 就会知道它是页面上唯一的元素。如果两个元素的 key 值不同,那么 Vue 便不会尝试复用 DOM。

这是 Vue 中虚拟 DOM 的一个 diff 算法里用到的内容,理解起来相对会比较深,我们可以暂时不用了解太多。只需要记住:给某个 DOM 元素上加一个 key 值,Vue 会发现这个 key 值与别的 DOM 元素的 key 值不一样,Vue 就不会复用这部分的内容

这样就可以避免刚才遇到的问题了。

祝好,qdywxs ♥ you!