2.6-2.7、条件&循环渲染

2.6、条件渲染

2.6.1 v-if

指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回true时才被渲染

2.6.2 v-else-if、v-else

顾名思义,v-else-if 提供的是相应于 v-if 的“else if 区块”。它可以连续多次重复使用。

一个使用 v-else-if 的元素必须紧跟在一个 v-if 或一个 v-else-if元素后面。

你也可以使用 v-else 为 v-if 添加一个“else 区块”,当然,v-else元素也是必须紧跟在一个 v-if 或一个 v-else-if元素后面。

需求:根据温度判断天气情况

<!-- v-if v-else-if v-else三者在使用的时候,中间不能断开。 -->
温度:<input type="number" v-model="temprature" ><br /><br />
天气:<span v-if="temprature <= 10">寒冷</span>
<span v-else-if="temprature <= 25">凉爽</span>
<span v-else>炎热</span>
<hr>

2.6.3 <template>与v-if

因为 v-if 是一个指令,他必须依附于某个元素。

但如果我们想要切换不止一个元素呢?

在这种情况下我们可以在一个 <template> 元素上使用 v-if,

这只是一个不可见的包装器元素,最后渲染的结果并不会包含个 <template> 元素。v-else 和 v-else-if 也可以在 <template> 上使用。

<!--3、 template标签/元素只是起到占位的作用,不会真正的出现在页面上,也不会影响页面的结构。 -->
   <template v-if="counter === 10">
      <h2>六下匹,人当送,内。</h2>
      <h3>六下匹,人当送,内。</h3>
      <h4>六下匹,人当送,内。</h4>
    </template>

2.6.4 v-show

另一个可以用来按条件显示一个元素的指令是 v-show。其用法基本一样:

  <div v-show="false">v-show-{{msg}}</div>
  <div v-show="2 === 1">v-show-{{msg}}</div>

不同之处在于 v-show 会在 DOM 渲染中保留该元素;v-show 仅切换了该元素上名为 display 的 CSS 属性。

不能和 v-else 搭配使用。

2.6.5 v-if VS v-show

v-if 是“真实的”按条件渲染,因为它确保了在切换时,条件区块内的事件监听器和子组件都会被销毁与重建

v-if 也是惰性的:如果在初次渲染时条件值为 false,则不会做任何事。条件区块只有当条件首次变为 true 时才被渲染。相比之下,v-show 简单许多,元素无论初始条件如何,始终会被渲染,只有 CSS display属性会被切换。

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

2.7、循环渲染

语法格式:v-for指令。该指令用在被遍历的标签上。

v-for="(element, index) in elements" :key="element.id"

或者

v-for="(element, index) of elements" :key="element.id"

2.7.1 遍历数组、对象、字符串、指定次数

1、遍历对象
  <h2>遍历对象的属性</h2>
  <ul>
    <li v-for="(value, propertyName) of user">{{propertyName}},{{value}}</li>
  </ul>
  <hr />
2、遍历字符串
  <h2>遍历字符串</h2>
  <ul>
    <li v-for="(c,index) of str">{{index}},{{c}}</li>
  </ul>
  <hr />
3、遍历指定次数
  <h2>遍历指定的次数</h2>
    <ul>
      <li v-for="(num,index) of counter">{{index}}, {{num}}</li>
    </ul>
    <hr />
4、遍历数组
 <h2>遍历数组</h2>
      <!-- 静态列表 -->
      <ul>
        <li>张三</li>
        <li>李四</li>
        <li>王五</li>
      </ul>

      <!-- 动态列表 -->
      <ul>
        <!-- 
                1. v-for要写在循环项上。
                2. v-for的语法规则:
                    v-for="(变量名,index) in/of 数组"
                    变量名 代表了 数组中的每一个元素
             -->
        <li v-for="(name,index) of names">{{name}}-{{index}}</li>
      </ul>

      <table>
        <tr>
          <th>序号</th>
          <th>会员名</th>
          <th>年龄</th>
          <th>选择</th>
        </tr>
        <tr v-for="(vip,index) in vips">
          <td>{{index+1}}</td>
          <td>{{vip.name}}</td>
          <td>{{vip.age}}</td>
          <td><input type="checkbox" /></td>
        </tr>
      </table>

2.7.2 虚拟dom和diff算法

虚拟DOM:在内存中的dom对象

diff算法:是一种能够快速的比较出两个事物不同之处的算法

v-for指令所在的标签中,还有一个非常重要的属性::key

如果没有指定 :key 属性,会自动拿index作为key。这个key是这个dom元素的身份证号/唯一标识。

1、 虚拟DOM中key的作用(diff到底是怎么做对比?):

key是虚拟DOM中对象的标识,当数据发生变化时,Vue会根据新数据生成新的虚拟DOM,随后Vue进行新虚拟DOM与旧虚拟DOM的差异比较,比较规则如下

a:旧虚拟DOM中找到与新虚拟DOM中相同的key

若虚拟DOM中内容没变,直接使用之前的真实DOM

若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM

b:旧虚拟DOM中未找到与新虚拟DOM相同的key,则直接创建新的真实DOM,随后渲染到页面

2、 用index作为key可能会引发的问题

a:若对数据进行逆序添加、逆序删除等破坏顺序操作,会产生没有必要的真实DOM更新,当然界面渲染没有问题,就是效率低

b:若结构中还包含输入类的DOM:会产生错误DOM更新,也就是界面有问题

3、开发中如何选择key

a:最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值

b:如果不存在对数据的逆序添加,逆序删除等破坏顺序的操作,仅用于渲染列表,使用index作为key是没有问题的

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>虚拟dom与diff算法</title>
    <script src="../js/vue.js"></script>
    <style>
      th,
      td {
        border: 1px solid black;
      }
    </style>
  </head>
  <body>
    <!-- 
    需求1、在数组的最后添加一个数据
    需求2、在数组的前面添加一个数据
    
        v-for指令所在的标签中,还有一个非常重要的属性::key
        如果没有指定 :key 属性,会自动拿index作为key。
        这个key是这个dom元素的身份证号/唯一标识。

        分析以下:采用 index 作为key存在什么问题?
            第一个问题:效率低。
            第二个问题:非常严重了。产生了错乱。尤其是对数组当中的某些元素进行操作。(非末尾元素。)
        怎么解决这个问题?
            建议使用对象的id作为key
        -->
    <div id="app">
      <h1>{{msg}}</h1>
      <table>
        <tr>
          <th>序号</th>
          <th>英雄</th>
          <th>能量值</th>
          <th>选择</th>
        </tr>
        <!-- 这种写法会出现错乱 -->
        <tr v-for="(hero,index) in heros" :key="index">
          <td>{{index+1}}</td>
          <td>{{hero.name}}</td>
          <td>{{hero.power}}</td>
          <td><input type="checkbox" /></td>
        </tr>
      </table>

      <button @click="add">添加英雄麦文</button>
    </div>
    <script>
      const vm = new Vue({
        el: "#app",
        data: {
          msg: "虚拟dom与diff算法",
          heros: [
            { id: "101", name: "艾格文", power: 10000 },
            { id: "102", name: "麦迪文", power: 9000 },
            { id: "103", name: "古尔丹", power: 8000 },
            { id: "104", name: "萨尔", power: 6000 },
          ],
        },
        methods: {
          add() {
            this.heros.unshift({ id: "105", name: "麦文", power: 9100 });
          },
        },
      });
    </script>
  </body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值