虚拟dom -> diff算法 -> key
原生的document.createElement -> 真实dom (对象上的属性和方法太多了,所以频繁操作真实的dom性能不好),可以自己打印看一下,属性看着眼睛都花了,特别多。
在vue中 h(createElement) -> 虚拟dom 虚拟dom就是一个普通的对象 就是对真实的dom的一个描述 ,操作虚拟dom不会导致重绘和回流;
没了解这个之前 我们操作了数据,会观察到视图更新,我们以为是数据改了,dom就会更新
但是其实不是这样的:
页面打开的时候 构造内存中的虚拟dom -> 根据虚拟dom构建真实的dom
虚拟dom就是一个普通的js对象 就是对真实的dom的一个描述,提高了更新DOM的性能(不用把页面全删除重新渲染),虚拟DOM只包含必要的属性 轻量级
当data中数据改变的时候,会创建出来一个新的虚拟dom ,新旧虚拟dom就会对比(发现有不同,怎么找不同的,可以看下面的diff算法),就会对真实的dom进行补丁patch;
数据更新的时候 vue怎么玩的
1. 先生成一个新的虚拟dom
2. 新旧虚拟dom进行diff算法对比 (找不同)
3. 找到不同就打补丁
// diff算法 时间复杂度 -> O(n) 同级比较
// 1. 同级同一个位置的元素名变了 就直接这块销毁重建
// 2. 同级同一个位置元素没有变,只有属性或内容变了,只更新属性或内容
// 3. 如何确定变还是没有变 这块就涉及到一个东西叫key (key一样就会被认为是同一个东西)
(1). 没有key 就会就地复用 :如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法。(如果同一个位置的元素相同就会被认为是同一个元素)
(2). 有key,但是key用的是索引(key一样就会被认为是同一个元素) 和没有key作用没有区别 还是就地更新
(3). 有key,但是key是编码,比如id值
// 1. 如果key一样 就会被认为是同一个元素
// 2. 如果key不一样,就会被认为不同的元素
// 3. 如果没有key,元素名不一样,就会被认为不同的元素 如果元素名一样就会被认为是同一个元素 就地复用
没有key或者有key但是用的是索引,有时候会出bug
有时候不写key会报错,那么如果有id就用id作为key,如果没有id只能用索引(key必须是一个唯一的值)
写法有二种
{/* <li v-for="item in arr" :key="item.id"> 适合数据是一个对象,并且对象中有id的时候 */ }
<li v-for="(item,index) in arr" :key="index"></li> 适合于数据中没有id的时候
// 虚拟dom
// 好处:减少重绘和回流的次数
// 数据更新,流程
// diff算法 1. 同级比较 2. 注意区分有没有key以及key是索引还是id的区别,平时最好写上key值