八、vue-基础之列表渲染v-for、v-for中的key属性的作用

一、v-for列表渲染

在真实开发中,我们往往会从服务器拿到一组数据,并且需要对其进行渲染。

  • 这个时候我们可以使用v-for来完成;
  • v-for类似于JavaScript的for循环,可以用于遍历一组数据;

 

二、v-for基本使用

(1)遍历数组

我们直接上demo~ 

<!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">
      <!-- 1. 遍历数组 -->

      <!-- 2. 遍历对象 -->
      <ul>
        <!-- 2.1 一个参数 -->
        <li v-for="value in info">{{value}}</li>
      </ul>

      <ul>
        <!-- 2.2 两个参数 -->
        <li v-for="(value, key) in info">{{value}} - {{key}}</li>
      </ul>

      <ul>
        <!-- 2.3 三个参数 -->
        <li v-for="(value, key, index) in info">{{value}} - {{key}} - {{index}}</li>
      </ul>
    </div>
    <script src="../lib/vue.js"></script>

    <script>
      const app = Vue.createApp({
        // data: option api
        data() {
          return {
            message: "Hello Vue",
            movies: [],
            info: { name: "daxia", age: 18, height: 1.88 },
          }
        },
      })

      app.mount("#app")
    </script>
  </body>
</html>

(2) 遍历对象

 

<!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">
      <!-- 1. 遍历数组 -->

      <!-- 2. 遍历对象 -->
      <ul>
        <!-- 2.1 一个参数 -->
        <li v-for="value in info">{{value}}</li>
      </ul>

      <ul>
        <!-- 2.2 两个参数 -->
        <li v-for="(value, key) in info">{{value}} - {{key}}</li>
      </ul>

      <ul>
        <!-- 2.3 三个参数 -->
        <li v-for="(value, key, index) in info">{{value}} - {{key}} - {{index}}</li>
      </ul>
    </div>
    <script src="../lib/vue.js"></script>

    <script>
      const app = Vue.createApp({
        // data: option api
        data() {
          return {
            message: "Hello Vue",
            movies: [],
            info: { name: "daxia", age: 18, height: 1.88 },
          }
        },
      })

      app.mount("#app")
    </script>
  </body>
</html>

(3)遍历字符串

 

(4)遍历数字

 

三、数组更新检测

 我们上代码~

<!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>
      <button @click="changeArray">修改数组</button>
    </div>
    <script src="../lib/vue.js"></script>

    <script>
      const app = Vue.createApp({
        // data: option api
        data() {
          return {
            names: ["abc", "cba", "nba", "aaa", "ccc"],
          }
        },
        methods: {
          changeArray() {
            // 1. 直接将数组修改为一个新的数组
            // this.names = ["why", "kobe"]

            // 2. 通过一些数组的方法,修改数组中的元素
            // this.names.push("why")
            // this.names.pop()

            // 索引,删除元素的个数(添加的话就是写0),
            // this.names.splice(2, 1, "why")

            // 排序
            // this.names.sort()

            // 反转
            this.names.reverse()
          },
        },
      })

      app.mount("#app")
    </script>
  </body>
</html>

注意:不修改原数组的方法是不能侦听(watch)

// 3. 不修改原数组的方法是不能侦听(watch)
const newNames = this.names.map((item) => item + "why")
this.names = newNames

 

四、v-for的key属性

 

(1) 认识VNode

我们先来解释一下VNode的概念:

  • 因为目前我们还没有比较完整的学习组件的概念,所以目前我们先理解HTML元素创建出来的VNode。
  • VNode的全称Virtual Node,也就是虚拟节点
  • 事实上,无论是组件还是元素,它们最终在Vue中表示出来的都是一个个VNode;
  • VNode的本质是一个JavaScript的对象;

 

 

 我们先来理解一下,现在id=app的div元素,是不是相当于模板,以前我们是写在下面的,现在写在了上面。

vue并不会根据你写的h2,直接去给你创建一个h2元素。如果直接给你#app.append(h2元素),追加了h2元素的话, 那此时不就是真实DOM的h2元素。

他会在生成真实DOM的h2元素之前,先生成一个VNode。

那VNode到底是一个什么东西呢?

答:VNode的本质是一个JavaScript的对象。他直接用一个JavaScript对象把他表现出来了,并没有直接给你表现出一个h2元素。

假如说你的模板里面有个div元素,他会先把你这个div元素先做一个解析(源码里其实有专门的一部分代码来解析下面这个div元素的,解析成VNode),解析成啥样子的?就是下方的图。本质上就是一个java Script对象。

 

 我们有了VNode,有直接转化成我们真实DOM里面的元素吗? 答:目前还没有。

当我们有了VNode之后,我们就可以对这个Vnode进行解析了。原来我们创建的元素是div元素,原来我们创建的元素的属性是...等等。最终的话再由我们的VNode转换成真实DOM里面的元素,转换成真实DOM里面的元素之后,我们才能在这是DOM里面看到该元素,在 用户界面才能看到。(先做一个了解,后面看源码)。

(2) 虚拟DOM

有童鞋好奇,为什么非要中间加一个虚拟节点、虚拟DOM这个概念,直接创建真实DOM不好吗?

这里最主要的原因有2个:

1. 如果我们当前有个虚拟DOM,方便他去做diff算法。(在下面第六点会提到)

2. 如果有了虚拟DOM,他方便对我们的代码进行跨平台。

我们可以通过虚拟DOM转换成真实DOM,并且渲染到浏览器上面

我们也可以通过虚拟DOM,解析这个java Script对象结构变成移动端的button/view/image等类似控件,然后渲染到移动端显示出来。

我们还可以通过虚拟DOM渲染到桌面端一些控件。

我们也可以渲染到VR设备。

(3)v-for的key属性的作用

了解了VNode、虚拟DOM和真实DOM的概念之后,我们再来看下v-for的key的属性的作用。

我们来个demo,我们想要在letters里面b和c之间插入一个f怎么做?

如果我们未插入一个f之前,我们已经有了虚拟DOM,然后通过原先的虚拟DOM创建了一个真实DOM。

这个时候我们由中间某一个位置给他插入一个东西的时候,我们思考下有几种做法?

1. 第一种,原来这些节点全部不要了, 我从a开始重新创建一个个节点,然后渲染成真实DOM。(没有必要这么去做,为什么?因为刚才的a节点,b节点没有发生变化。没有必要全部销毁从0开始)

2. 第二种, a b 保留,f替代原来c的位置,后面的都得修改。后面少一个了,就去新建e节点。

这种算法的效率不高,因为这里有很多c后面开始重新需要修改的。(他并不知道上面这个c和下面的这个c可以重复利用。这就是vue没有设置key的情况下的算法。仅在中间插入的时候是这样子,如果是在最后插入的话,是没什么区别的。

3. 第三种, 跟上面第二种的区别就是,我给每一个节点加个key。这样子第二次虚拟DOM的时候,我就能知道第一次虚拟DOM的c,d,e,都是可以重复利用的。

总结:所以 v-for 加key属性的作用就是让vue更快识别出来 两个节点是同一个东西。

没有key的diff算法: 

 

有key的diff算法:

 

  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值