Vue核心技术-4,条件渲染指令

一,前言

这两天会出一份目录,对之前的几篇也会重新编排,
并补充一些遗漏的知识点,例如插值部分的过滤器等等...

在没有目录的情况下,暂时先按照自己的想法把知识点更新上来
这一篇介绍Vue的条件渲染指令,包括v-if,v-else-if,v-else,v-show
这些指令虽然都是根据条件对页面进行显示的指令,但功能和使用上还是很值得考究的

二,v-if,v-else-if,v-else指令的简单介绍

和js语法中的条件语句if...else if...else类似,将这三个指令列为一组
Vue.js的条件指令也可以根据表达式的值,完成DOM中元素/组件的渲染和销毁
<div id="app">
  <p v-if="status === 1">当status等于1时显示此行</p>
  <p v-else-if="status === 2">当status等于2时显示此行</p>
  <p v-else>当status既不等于1也不等于2时显示此行</p>
</div>

<script type="text/javascript">
  var vm = new Vue({
    el: '#app',
    data: {
      status: 1
    }
  })
</script>
上面这个简单的例子,会根据status的值动态渲染页面完成显示

status=1:
v-if
此时DOM:
1-dom
通过dev-tools工具将status改为2:
这里写图片描述
此时DOM:
2-dom

从图中可以看到页面会随status值变化而同步变化,
且只显示status值对应的dom,其他dom并没有被渲染
当status由1变为2时,status=1的dom被销毁,status=2的dom被创建

三,v-show指令的简单介绍

v-show的用法和v-if相同,功能上很相似,也是控制元素的显示和隐藏
但两者对于显示隐藏式的实现方式不同,
v-show是通过改变元素CSS属性display实现显隐效果的
<div id="app">
  <p v-show="status === 1">当status等于1时显示此行</p>
</div>

<script type="text/javascript">
  var vm = new Vue({
    el: '#app',
    data: {
      status: 1
    }
  })
</script>

当status=1时,元素显示:
show1
此时DOM:
show1dom
使用devtools将status值修改为2,元素隐藏
show2
此时DOM:
show2dom

我们发现当v-show表达式为false时,元素隐藏,
与v-if不同的是,这个元素依然还存在于dom中,
只是被添加了style="display: none;"实现隐藏效果

注意:

在使用上和js相似,v-else-if需要紧跟v-if,v-else要紧跟v-else-if或v-if
当表达式为真时,相应的元素/组件及所有节点将被渲染,为假时将被移除

四,一次判断多个元素的显示隐藏

上面介绍了v-if和v-show的简单使用和区别
但上边的例子都是对的那个元素进行显示隐藏控制

在真实项目中,往往需要一次判断控制多个元素的显示隐藏
我们可以在多个元素上添加相同的判断条件,但这样会造成代码的冗余
我们也可以在外层套一个div做v-if或v-show的显隐判断,但这会导致渲染结果多出一个div
往往这个div并不是我们想要的

这是,我们可以在Vue内置的<template>元素上使用条件指令
最终渲染的结果不会包含该元素
<div id="app">
  <template v-if="status === 1">
    <p>项目一</p>
    <p>项目二</p>
    <p>项目三</p>
  </template>
</div>

<script type="text/javascript">
  var vm = new Vue({
    el: '#app',
    data: {
      status: 1
    }
  })
</script>

templateif

在<template>元素上使用条件指令v-if,最终渲染的结果不包含该元素

注意:

v-show不能用于<template>元素,无论v-show值是否为真,元素始终都会显示

五,v-if和v-show的比较

v-if和v-show从功能上将都是实现控制显示隐藏
存在必有道理,对于v-if和v-show的选择是几乎所有Vue面试题都有的一道题

严格来说v-if才是真正的条件渲染,因为它会根据表达式创建/销毁元素及绑定事件或子组件
若初始化表达式为false,则元素/组件不会被渲染,只有当表达式第一次为真时才开始编译

v-show只是简单的CSS属性切换,不管表达式是否为真都会被编译

对于v-if和v-show的选择没有绝对的对错,这要看场景的需要
v-if更适合条件不经常变化的场景,因为频繁的创建会造成较大的开销,效率也较低
v-show更适合频繁的切换,因为dom中一直存在,只是在更改CSS而已

六,Diff算法导致的元素/组件复用问题

现在很多网站的登录页面都支持多种登录方式:用户名,邮箱,各种第三方登录等等

现以用户名和邮箱作为两种不同类型的登录方式供用户进行切换选择
<div id="app">
  <template v-if="type === 'name'">
    <label>用户名:</label>
    <input placeholder="请输入用户名">
  </template>
  <template v-if="type === 'email'">
    <label>邮箱:</label>
    <input placeholder="请输入邮箱">
  </template>
  <br>
  <br>
  <button @click="toggle">切换账户类型:用户名/邮箱</button>
</div>

<script type="text/javascript">
  var vm = new Vue({
    el: '#app',
    data: {
      type:'name'
    },
    methods:{
      toggle: function () {
        this.type = this.type === 'name' ? 'email' : 'name';
      }
    }
  })
</script>

运行结果:

name

点击切换按钮,显示邮箱输入:

email

以上测试了基本功能的实现,再做一个测试:在用户名类型的input中输入一个用户名,再点击切换按钮

nameBrave

切换至邮箱登录:
emailBrave

通过和之前测试的观察发现:

填写用户名的情况下,切换登录类型,邮箱登录的input会使用用户名填写的value值

这是因为:

Vue在渲染元素时会使用Diff算法对已有组件进行最大限度的复用而非重新渲染,以提升效率
输入内容后切换输入类型,虽然DOM变化但内容没有改变,只替换了placeholder,说明<input>被复用

如果不希望这样做

有些时候,Vue的这种机制并不是我们想要的,这时可以使用Vue.js提供的key属性
由key值决定是否复用以后元素,key值必须唯一
<div id="app">
  <template v-if="type === 'name'">
    <label>用户名:</label>
    <input placeholder="请输入用户名" key="name-input">
  </template>
  <template v-if="type === 'email'">
    <label>邮箱:</label>
    <input placeholder="请输入邮箱" key="email-input">
  </template>
  <br>
  <br>
  <button @click="toggle">切换账户类型:用户名/邮箱</button>
</div>

<script type="text/javascript">
  var vm = new Vue({
    el: '#app',
    data: {
      type:'name'
    },
    methods:{
      toggle: function () {
        this.type = this.type === 'name' ? 'email' : 'name';
      }
    }
  })
</script>
通过以上简单的修改,为两个<input>元素添加key,不会再产生复用效果
当键入内容后点击切换按钮,内容不会被复用
由于<label>元素没有添加key,此时仍然是被服用的

七,结尾

关于Vue条件渲染指令的内容就先说这些,
对于key的使用更多的情况出现在v-for循环中,
下一节列表渲染指令v-for...

猜你喜欢

转载自blog.csdn.net/ABAP_Brave/article/details/81712254