写点什么

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

  • 2024-02-06
    福建
  • 本文字数:2898 字

    阅读完需:约 10 分钟

听我说


从 条件渲染 那一篇,我学习到了如何用 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

体验地址:http://www.jnpfsoft.com/?from=001

用户头像

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
零基础入门Vue之影分身之术——列表渲染&渲染原理浅析_Java_不在线第一只蜗牛_InfoQ写作社区