零基础入门Vue之影分身之术——列表渲染&渲染原理浅析

听我说

条件渲染 那一篇,我学习到了如何用Vue对dom节点根据条件显示

但单单有条件还不够啊,有时候数据是一大坨一大坨的数据,如果Vue不提供咱要么使用"v-html" 要么就没办法实现

v-html又感觉太low了,Vue提供了另外的指令更好的实现,那便是:列表渲染

列表渲染:v-for

简单的列表渲染可以使用v-for来完成,而Vue提供了两种采用形式的列表渲染

列表渲染之数组

假设我有一个数组,然后我希望数组里面的数据,通过展示在ul的一个一个li里面,并且要求数组更新的同时li会自动的增减

假设data如下

//假设下面是Vue的配置对象
{
  data:{
    msgList:[
      {
        name:"张三",
        age:19,
        sex:"男"
      },
      {
        name:"李四",
        age:22,
        sex:"男"
      },
      {
        name:"王五",
        age:20,
        sex:"女"
      },
      {
        name:"陈真",
        age:30,
        sex:"男"
      },
    ]
  }
}

那么dom节点可以这么写,达到渲染的效果

<!--假设这是根节点的内容-->
<ul>
  <li v-for="item of msgList">
    {{item.name}} - {{item.age}} - {{item.sex}}
  </li>
</ul>

此时,ul里面的li渲染出的个数等同于msgList的个数,同时item表示当前li的数组元素

可以用JavaScript的for-of循环来理解,这里用v-for="item in msgList"也是一样的效果

item都是表示msgList的成员

完整代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="./vue.js"></script>
    <title>Document</title>
</head>
<body>
    <div id="root">
        <ul>
            <li v-for="item of msgList">
              {{item.name}} - {{item.age}} - {{item.sex}}
            </li>
        </ul>
    </div>
</body>
<script>
    let vm = new Vue({
        el:"#root",
        data:{
            msgList:[{
                name:"张三",
                age:19,
                sex:"男"
            },
            {
                name:"李四",
                age:22,
                sex:"男"
            },
            {
                name:"王五",
                age:20,
                sex:"女"
            },
            {
                name:"陈真",
                age:30,
                sex:"男"
            }]
        }
    })
</script>
</html>

列表渲染之对象

Vue还允许配置为对象这种可遍历的变量来使用v-for

如果配置为对象的话,那么会拿到两个参数,一个是key一个是value(先拿到value在拿到key

具体代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="./vue.js"></script>
    <title>Document</title>
</head>
<body>
    <div id="root">
        <ul>
            <li v-for="(value,key) of msgObj">
              {{key}} - {{value}}
            </li>
        </ul>
    </div>
</body>
<script>
    let vm = new Vue({
        el:"#root",
        data:{
            msgObj:{
                name:"陈真",
                age:30,
                sex:"男"
            }
        }
    })
</script>
</html>

当然也可以写一个参数,只接受value

<div id="root">
    <ul>
        <li v-for="value of msgObj">
          {{value}}
        </li>
    </ul>
</div>

完全写法

无论是对象还是数组,列表渲染都会给当前值索引,所以对于数组的话就可以写成两个参数,显示value后是索引

<ul>
    <li v-for="(item,index) of msgList">
      {{index}}、{{item.name}} - {{item.age}} - {{item.sex}}
    </li>
</ul>

如何使对象的话就这么写

<ul>
    <li v-for="(value,key,index) of msgObj">
      {{index}}、{{key}} = {{value}}
    </li>
</ul>

key的应用&渲染原理浅析

为了避免出错,无论是react还是vue使用v-for,原则上都应该配置唯一标识作为key

当出现要对数据修改时,未配置唯一标识key可能会出现bug

因此对于需要用上v-for的节点请配置上数据唯一标识作为key

浅析出错原因

Vue在监控到数据改变时,并不会如我们所想的一样马上渲染dom

而是会先渲染虚拟dom,然后通过特定算法或者说特定规则去渲染实际dom

渲染规则如下:

  • 当遇到v-for时,首先寻找数据老的虚拟dom和新的虚拟dom的唯一标识进行对比(以li为例)

  • 在li节点中,如果有一样的部分那么照搬老的dom,不重新渲染,直接搬运反之根据新的虚拟dom重新渲染

  • 如果li中这个节点在旧虚拟dom不存在,那么久会按照新的虚拟dom重新渲染

key的具体用法

key 的特殊 attribute 主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes。如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法。而使用 key 时,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。

对于 Vue中的key 的用法也很简单,他是为了标识v-for每个循环元素的唯一性,所以key也应该是唯一的

写法如下

<dom v-for="item in list" :key="item.id"></dom>

此时,当前dom与数据唯一的id互相绑定,这样如果dom更新了,新旧虚拟dom就能一一对应的去对比

就不会出现元素紊乱,并且渲染效率低下的问题

具体代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="./vue.js"></script>
    <title>Document</title>
</head>
<body>
    <div id="root">
        <ul>
            <li v-for="item of msgList" :key="item.id">
              {{item.name}} - {{item.age}} - {{item.sex}}
            </li>
        </ul>
    </div>
</body>
<script>
    let vm = new Vue({
        el:"#root",
        data:{
            msgList:[{
                id:1,
                name:"张三",
                age:19,
                sex:"男"
            },
            {
                id:2,
                name:"李四",
                age:22,
                sex:"男"
            },
            {
                id:3,
                name:"王五",
                age:20,
                sex:"女"
            },
            {
                id:4,
                name:"陈真",
                age:30,
                sex:"男"
            }]
        }
    })
</script>
</html>

注:切忌把索引作为key,因为只要不是往末尾插入数据或者删除数据的方式来修改数据,都会造成index失去唯一标识的作用

文章转载自:StarVik

原文链接: https://www.cnblogs.com/Star-Vik/p/18008874

体验地址: 引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构

相关推荐
Json_1817901448013 分钟前
电商拍立淘按图搜索API接口系列,文档说明参考
前端·数据库
风尚云网36 分钟前
风尚云网前端学习:一个简易前端新手友好的HTML5页面布局与样式设计
前端·css·学习·html·html5·风尚云网
木子020439 分钟前
前端VUE项目启动方式
前端·javascript·vue.js
GISer_Jing41 分钟前
React核心功能详解(一)
前端·react.js·前端框架
捂月44 分钟前
Spring Boot 深度解析:快速构建高效、现代化的 Web 应用程序
前端·spring boot·后端
深度混淆1 小时前
实用功能,觊觎(Edge)浏览器的内置截(长)图功能
前端·edge
Smartdaili China1 小时前
如何在 Microsoft Edge 中设置代理: 快速而简单的方法
前端·爬虫·安全·microsoft·edge·社交·动态住宅代理
秦老师Q1 小时前
「Chromeg谷歌浏览器/Edge浏览器」篡改猴Tempermongkey插件的安装与使用
前端·chrome·edge
滴水可藏海1 小时前
Chrome离线安装包下载
前端·chrome
endingCode1 小时前
45.坑王驾到第九期:Mac安装typescript后tsc命令无效的问题
javascript·macos·typescript