1.13 列表渲染
v-for指令
- 用于展示列表数据
- 语法:v-for="(item, index) in xxx" :key="yyy"
- 可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)
<div id="root"> <!-- 遍历数组 --> <h2>人员列表(遍历数组)</h2> <ul> <li v-for="(p,index) of persons" :key="index"> {{p.name}}-{{p.age}} </li> </ul> <!-- 遍历对象 --> <h2>汽车信息(遍历对象)</h2> <ul> <li v-for="(value,k) of car" :key="k"> {{k}}-{{value}} </li> </ul> <!-- 遍历字符串 --> <h2>测试遍历字符串(用得少)</h2> <ul> <li v-for="(char,index) of str" :key="index"> {{char}}-{{index}} </li> </ul> <!-- 遍历指定次数 --> <h2>测试遍历指定次数(用得少)</h2> <ul> <li v-for="(number,index) of 5" :key="index"> {{index}}-{{number}} </li> </ul> </div> <script> const vm = new Vue({ el:'#root', data: { persons: [ { id: '001', name: '张三', age: 18 }, { id: '002', name: '李四', age: 19 }, { id: '003', name: '王五', age: 20 } ], car: { name: '奥迪A8', price: '70万', color: '黑色' }, str: 'hello' } }) </script>
key的原理
vue中的key有什么作用?(key的内部原理)
了解vue中key的原理需要一些前置知识。
就是vue的虚拟dom,vue会根据 data中的数据生成虚拟dom,如果是第一次生成页面,就将虚拟dom转成真实dom,在页面展示出来。
虚拟dom有啥用?每次vm._data 中的数据更改,都会触发生成新的虚拟dom,新的虚拟dom会跟旧的虚拟dom进行比较,如果有相同的,在生成真实dom时,这部分相同的就不需要重新生成,只需要将两者之间不同的dom转换成真实dom,再与原来的真实dom进行拼接。我的理解是虚拟dom就是起到了一个dom复用的作用,还有避免重复多余的操作,下文有详细解释。
而key有啥用?
key是虚拟dom的标识。
先来点预备的知识:啥是真实 DOM?真实 DOM 和 虚拟 DOM 有啥区别?如何用代码展现真实 DOM 和 虚拟 DOM
真实DOM
和其解析流程
这里参考超级英雄大佬:juejin.cn/post/684490…
webkit
渲染引擎工作流程图
中文版
所有的浏览器渲染引擎工作流程大致分为5步:创建 DOM
树 —> 创建 Style Rules
-> 构建 Render
树 —> 布局 Layout
-—> 绘制 Painting
。
- 第一步,构建 DOM 树:当浏览器接收到来自服务器响应的HTML文档后,会遍历文档节点,生成DOM树。需要注意的是在DOM树生成的过程中有可能会被CSS和JS的加载执行阻塞,渲染阻塞下面会讲到。
- 第二步,生成样式表:用 CSS 分析器,分析 CSS 文件和元素上的 inline 样式,生成页面的样式表;
- 渲染阻塞:当浏览器遇到一个script标签时,DOM构建将暂停,直到脚本加载执行,然后继续构建DOM树。每次去执行Javascript脚本都会严重阻塞DOM树构建,如果JavaScript脚本还操作了CSSOM,而正好这个CSSOM没有下载和构建,那么浏览器甚至会延迟脚本执行和构建DOM,直到这个CSSOM的下载和构建。所以,script标签引入很重要,实际使用时可以遵循下面两个原则:
- css优先:引入顺序上,css资源先于js资源
- js后置:js代码放在底部,且js应尽量少影响DOM构建
还有一个小知识:当解析html时,会把新来的元素插入dom树里,同时去查找css,然后把对应的样式规则应用到元素上,查找样式表是按照从右到左的顺序匹配的例如:div p {...},会先寻找所有p标签并判断它的父标签是否为div之后才决定要不要采用这个样式渲染。所以平时写css尽量用class或者id,不要过度层叠
- 第三步,构建渲染树:通过DOM树和CSS规则我们可以构建渲染树。浏览器会从DOM树根节点开始遍历每个可见节点(注意是可见节点)对每个可见节点,找到其适配的CSS规则并应用。渲染树构建完后,每个节点都是可见节点并且都含有其内容和对应的规则的样式。这也是渲染树和DOM树最大的区别所在。渲染是用于显示,那些不可见的元素就不会在这棵树出现了。除此以外,display none的元素也不会被显示在这棵树里。visibility hidden的元素会出现在这棵树里。
- 第四步,渲染布局:布局阶段会从渲染树的根节点开始遍历,然后确定每个节点对象在页面上的确切大小与位置,布局阶段的输出是一个盒子模型,它会精确地捕获每个元素在屏幕内的确切位置与大小。
- 第五步,渲染树绘制:在绘制阶段,遍历渲染树,调用渲染器的paint()方法在屏幕上显示其内容。渲染树的绘制工作是由浏览器的UI后端组件完成的。
注意点:
1、DOM
树的构建是文档加载完成开始的? 构建 DOM
树是一个渐进过程,为达到更好的用户体验,渲染引擎会尽快将内容显示在屏幕上,它不必等到整个 HTML
文档解析完成之后才开始构建 render
树和布局。
2、Render
树是 DOM
树和 CSS
样式表构建完毕后才开始构建的? 这三个过程在实际进行的时候并不是完全独立的,而是会有交叉,会一边加载,一边解析,以及一边渲染。
3、CSS
的解析注意点?CSS
的解析是从右往左逆向解析的,嵌套标签越多,解析越慢。
4、JS
操作真实 DOM
的代价? 传统DOM结构操作方式对性能的影响很大,原因是频繁操作DOM结构操作会引起页面的重排(reflow)和重绘(repaint),浏览器不得不频繁地计算布局,重新排列和绘制页面元素,导致浏览器产生巨大的性能开销。直接操作真实DOM
的性能特别差,我们可以来演示一遍。
<div id="app"></div> <script> // 获取 DIV 元素 let box = document.querySelector('#app'); console.log(box); // 真实 DOM 操作 console.time('a'); for (let i = 0; i <= 10000; i++) { box.innerHTML = i; } console.timeEnd('a'); // 虚拟 DOM 操作 let num = 0; console.time('b'); for (let i = 0; i <= 10000; i++) { num = i; } box.innerHTML = num; console.timeEnd('b'); </script>