一、条件判断指令

1.1 前言

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

Vue中有如下指令来进行条件判断:

  • v-if

  • v-else

  • v-else-if

  • v-show

使用了上面指令的标签内容只有在指令条件为true时,才会被渲染出来。

1.2 v-if的渲染特性

  • v-if是惰性的;

  • 当条件为false时,其判断的内容完全不会被渲染或者会被销毁掉;

  • 当条件为true时,才会真正渲染条件块中的内容;

1.3 v-if、v-else、v-else-if 代码示例

<div id="app">
    <h1 v-if="score > 90">优秀</h1>
    <h2 v-else-if="score > 80">良好</h2>
    <h3 v-else-if="score >= 60">及格</h3>
    <h4 v-else>不及格</h4>
</div>

<script src="../lib/vue.js"></script>
<script>
    // 1.创建app
    const app = Vue.createApp({
        data() {
            return {
                score: 40
            }
        },
    })

    // 2.挂载app
    app.mount("#app")
</script>

1.4 使用template优化页面渲染性能

<div id="app">
    <!-- v-if="条件" -->
    <template class="info" v-if="Object.keys(info).length">
        <h2>个人信息</h2>
        <ul>
            <li>姓名: {{info.name}}</li>
            <li>年龄: {{info.age}}</li>
        </ul>
    </template>

    <!-- v-else -->
    <template v-else>
        <p>请输入个人信息后, 再进行展示~</p>
    </template>
</div>

<script src="../lib/vue.js"></script>
<script>
    // 1.创建app
    const app = Vue.createApp({
        data() {
            return {
                info: {}
            }
        }
    })

    // 2.挂载app
    app.mount("#app")
</script>

template这对标签,在最终的页面上并不会被渲染。

这样避免了在该标签的位置写一个多余的div去承载指令。

从而在一定程度上提示页面性能。

类似于小程序中的block。

1.5 v-show 代码示例

  <div id="app">
    <div>
      <button @click="toggle">切换</button>
    </div>
    
    <div v-show="isShowCode">
      	v-show
    </div>

    <div v-if="isShowCode">
     	v-if
    </div>
  </div>
  
  <script src="../lib/vue.js"></script>
  <script>
    // 1.创建app
    const app = Vue.createApp({
      data() {
        return {
          isShowCode: true
        }
      },

      methods: {
        toggle() {
          this.isShowCode = !this.isShowCode
        }
      }
    })

    // 2.挂载app
    app.mount("#app")
  </script>

1.6 v-if 和 v-show的区别

  • 用法区别:

    • v-show是不支持template

    • v-show不可以和v-else一起使用;

  • 渲染的区别:

    • v-show无论是否渲染到浏览器上,它的DOM实际都是有存在的,通过CSSdisplay属性来进行切换;
    • v-if当条件为false时,其对应的元素不会被渲染到DOM中;
  • 如何进行选择呢?

    • 如果元素需要在显示和隐藏之间频繁的切换,使用v-show
    • 如果元素不会频繁的发生切换,使用v-if

二、列表渲染指令

2.1 使用场景

开发中经常需要对一组数据进行渲染。这通常是一个数组,包含着许多对象数据。

这个时候我们可以使用v-for指令来完成。

它可以用于遍历一组数据,并渲染到页面上进行显示。

但是也不是说v-for指令只能遍历数组,其实只要是可迭代的数据,v-for指令都可以进行遍历渲染

2.2 v-for指令的语法格式

  • v-for的基本格式: “item in 数组”

    <ul>
    	<li v-for="item in movies">{{ movie }}</li>
    </ul>
    <ul>
        <li v-for="item in 100">{{item}}</li>
    </ul>
    
    • item是我们给每项元素起的一个别名,这个别名可以自定义,只是习惯把其中的一项数据命名为item
  • v-for的索引格式: “(item, index) in 数组”

    • 注意顺序:数组元素项item在前,索引项index在后。
  • v-for遍历对象,支撑下面三种格式:

    • 一个参数: “value in object”
    • 二个参数: “(value, key) in object”
    • 三个参数: "(value, key, index) in object
    • value 是当前项的属性值,value 是当前项的属性名,index当前项的索引

v-for也可以遍历其他可迭代对象,只要可迭代的数据类型都可以被v-for指令遍历

2.3 v-for遍历数组格式数据代码示例

<div id="app">
    <!-- 1.电影列表进行渲染 -->
    <h2>电影列表</h2>
    <ul>
        <li v-for="movie in movies">{{ movie }}</li>
    </ul>

    <!-- 2.电影列表同时有索引 -->
    <ul>
        <li v-for="(movie, index) in movies">{{index + 1}} - {{ movie }}</li>
    </ul>

    <!-- 3.遍历数组复杂数据 -->
    <h2>商品列表</h2>
    <div class="item" v-for="item in products">
        <h3>商品: {{item.name}}</h3>
        <span>价格: {{item.price}}</span>
        <p>秒杀: {{item.desc}}</p>
    </div>
</div>

<script src="../lib/vue.js"></script>
<script>
    // 1.创建app
    const app = Vue.createApp({
        data() {
            return {
                // 1.movies
                movies: ["星际穿越", "少年派", "大话西游"],

                // 2.数组: 存放的是对象
                products: [
                    { id: 110, name: "Macbook", price: 9.9, desc: " 快来抢购!" },
                    { id: 111, name: "iPhone", price: 8.8, desc: "快来抢购!" },
                    { id: 112, name: "小米电脑", price: 9.9, desc: " 快来抢购!" },
                ]
            }
        },
    })

    // 2.挂载app
    app.mount("#app")
</script>

2.4 v-for遍历对象、字符串、数字格式数据代码示例

<div id="app">
    <!-- 1.遍历对象 -->
    <ul>
        <li v-for="(value, key, index) in info">{{value}}-{{key}}-{{index}}</li>
    </ul>

    <!-- 3.遍历字符串(iterable) -->
    <ul>
        <li v-for="item in message">{{item}}</li>
    </ul>

    <!-- 4.遍历数字 -->
    <ul>
        <li v-for="item in 100">{{item}}</li>
    </ul>
</div>

<script src="../lib/vue.js"></script>
<script>
    // 1.创建app
    const app = Vue.createApp({
        data() {
            return {
                message: "Hello Vue",
                info: { name: "张三", age: 18, height: 1.78 }
            }
        },
    })

    // 2.挂载app
    app.mount("#app")
</script>

2.5 使用template优化多余的div

<div id="app">
    <!-- 如果包裹内容的div没有实际的意义, 那么可以使用template替换 -->
    <template v-for="(value, key, index) in infos">
        <span>{{value}}</span>
        <strong>{{key}}</strong>
        <i>{{index}}</i>
    </template>
</div>

<script src="../lib/vue.js"></script>
<script>
    // 1.创建app
    const app = Vue.createApp({
        data() {
            return {
                info: { name: "张三", age: 18, height: 1.78 }
            }
        },
    })

    // 2.挂载app
    app.mount("#app")
</script>

三、数组更新监测

3.1 能够被Vue监测到的数组更新方法

Vue 将被侦听的数组的变更方法进行了包裹,它们的使用会触发视图更新。

这些被包裹过的方法包括:

  • push() – 将一个或多个元素添加到数组的末尾,并返回该数组的新长度

  • pop() – 从数组中删除最后一个元素,并返回该元素的值

  • shift() – 从数组中删除第一个元素,并返回该元素的值

  • unshift() – 将一个或多个元素添加到数组的开头,并返回该数组的新长度

  • splice() – 删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容

  • sort() – 对数组的元素进行排序,并返回数组

  • reverse() – 将数组中元素的位置颠倒,并返回该数组

3.2 不能够被Vue监测到的数组更新方法

不修改原数组的方法是不能被Vue侦听到,并且渲染到页面上的。

比如:

  • filter() – 对满足条件的数据进行过滤,返回一个新数组
  • concat() – 用于合并两个或多个数组,返回一个新数组
  • slice() – 按 beginend 截取的原数组的浅拷贝(包括 begin,不包括end),返回一个新数组
  • map() – 按函数进行数组各项元素的转换,返回一个新数组

除了上面的方法外,其它不修改原数组而返回一个新数组的方法不能被Vue侦听到。

就看会不会修改原数组,会修改原数组的方法,就会触发视图更新。

四、v-for中的key属性

4.1 v-for中的key属性的使用示例

<div id="app">
    <button @click="insertF">插入f</button>
    <ul>
        <!-- key要求是必须唯一 -->
        <!-- 如果数据中有id可以使用id做key, 没id则使用索引 -->
        <li v-for="(item, index) in letters" :key="index">{{item}}</li>
    </ul>
</div>

<script src="../lib/vue.js"></script>
<script>
    // 1.创建app
    const app = Vue.createApp({
        // data: option api
        data() {
            return {
                letters: ["a", "b", "c", "d", "e"]
            }
        },
        methods: {
            insertF() {
                this.letters.splice(2, 0, "f")
                this.letters.splice()
            }
        }
    })

    // 2.挂载app
    app.mount("#app")
</script>

4.2 为什么使用key属性

在使用v-for进行列表渲染时,我们通常会给元素或者组件绑定一个key属性。

这个key属性的官方解释:

  • key属性主要用在Vue的虚拟DOM算法,在新旧nodes对比时辨识VNodes

  • 不使用keyVue会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法;

  • 使用key时,它会基于key的变化重新排列元素顺序,并且会移除/销毁key不存在的元素;

4.3 什么是VNode

VNode的全称是Virtual Node,也就是虚拟节点。

实际上,无论是组件还是元素,它们最终在Vue中表示出来的都是一个个VNode

但是VNode的本质依旧是一个JavaScript的对象。

Vue中,template模板选项会先转换成VNode,最后再转换成浏览器上显示的真实DOM

4.4 什么是虚拟Dom

如果有一大堆的元素,Vue会将所有元素都渲染成一个个VNode,形成一个VNode Tree

这个VNode Tree就是虚拟DOM

它的本质是保存DOM关键信息的js对象。

标签到虚拟DOM和真实DOM的转换过程:

在这里插入图片描述

为什么不直接转换成真实DOM,而是要借助虚拟DOM呢?

  • 更有利于进行diff算法分析

  • 有利于代码的跨平台。

    • 虚拟DOM可以根据不同的平台解析成不同形式的元素,实现一份代码多平台复用。

4.5 diff算法

diff算法是一种用来比较新旧虚拟DOM的算法,用来提升程序的执行效率。

具体比较方式:

  • 根元素改变 – 删除当前DOM树重新建

  • 根元素未变, 属性改变 – 更新属性

  • 根元素未变, 子元素/内容改变

有无key的区别:

  • key – 就地更新,Vue底层执行patchUnkeyedChildren方法
  • key – 按key比较,Vue底层执行patchKeyedChildren方法

好处:

  • 在没有key的时候我们的效率是非常低效的

  • 在进行插入或者重置顺序的时候,保持相同的key可以让diff算法更加的高效

Logo

前往低代码交流专区

更多推荐