什么是虚拟dom
用js来描述元素与元素之间的关系 [父子 兄弟]
目的:高效渲染 以及快速更新
高效渲染和快速更新的手段是diff算法
diff算法
Diff算法就是在虚拟DOM树从上至下进行同层比对,如果上层已经不同了,那么下面的DOM全部重新渲染。这样的好处是算法简单,减少比对次数,加快算法完成速度。
diff 算法是⼀种通过同层的树节点进⾏⽐较的⾼效算法
其有两个特点:
diff 算法在很多场景下都有应⽤,在 vue 中,作⽤于虚拟 dom 渲染成真实 dom 的新旧 VNode 节点 ⽐较
⼆、⽐较⽅式 diff 整体策略为:深度优先,同层⽐较
1. ⽐较只会在同层级进⾏, 不会跨层级比较
2. ⽐较的过程中,循环从两边向中间收拢
下⾯举个 vue 通过 diff 算法更新的例⼦:
新旧 VNode 节点如下图所示
第⼀次循环后,发现旧节点D与新节点D相同,直接复⽤旧节点D作为 diff 后的第⼀个真实节点,同时 旧节点 endIndex 移动到C,新节点的 startIndex 移动到了c
第⼆次循环后,同样是旧节点的末尾和新节点的开头(都是 C)相同,同理, diff 后创建了 C 的真实节点 插⼊到第⼀次创建的 B 节点后⾯。同时旧节点的 endIndex 移动到了 B,新节点的 startIndex 移动 到了E
第三次循环中,发现E没有找到,这时候只能直接创建新的真实节点 E,插⼊到第⼆次创建的 C 节点之 后。同时新节点的 startIndex 移动到了 A。旧节点的 startIndex 和 endIndex 都保持不动
第四次循环中,发现了新旧节点的开头(都是 A)相同,于是 diff 后创建了 A 的真实节点,插⼊到前⼀ 次创建的 E 节点后⾯。同时旧节点的 startIndex 移动到了 B,新节点的 startIndex 移动到了 B
第五次循环中,情形同第四次循环⼀样,因此 diff 后创建了 B 真实节点 插⼊到前⼀次创建的 A 节点 后⾯。同时旧节点的 startIndex 移动到了 C,新节点的 startIndex 移动到了 F
新节点的 startIndex 已经⼤于 endIndex 了,需要创建 newStartIdx 和 newEndIdx 之间的所有 节点,也就是节点F,直接创建 F 节点对应的真实节点放到 B 节点后⾯
三、原理分析 当数据发⽣改变时, set ⽅法会调⽤ Dep.notify 通知所有订阅者 Watcher ,订阅者就会调⽤ patch 给真实的 DOM 打补丁,更新相应的视图
什么是插槽
(在子组件中用<slot></slot>划出一块区域来显示父组件中的页面结构,显示的结构在父组件的子组件标签中设置就行)
插槽怎么显示数据
显示的结构在父组件的子组件标签中设置就行
插槽分为几种
默认插槽 具名插槽 作用域插槽
作用域插槽怎么用
在子组件<slot></slot>通过v-bind绑定一个属性,挂载变量
<slot name="content" v-bind:us="user"></slot>
在父组件中子组件标签上通过v-slot:插槽名=“变量”来接受数据
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined, undefined, null,null, NaN,NaN,'NaN', 0, 0, 'a', 'a',{},{}]; function arr_unique1(arr){ return [...new Set(arr)]; //或者 //return Array.from(new Set(arr)); } arr_unique1(arr); // (13)[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]
function arr_unique2(arr) { let map = new Map(); let array = new Array(); // 数组用于返回结果 for (let i = 0; i < arr.length; i++) { if(map .has(arr[i])) { // 如果有该key值 map .set(arr[i], true); } else { map .set(arr[i], false); // 如果没有该key值 array .push(arr[i]); } } return array ; } console.log(arr_unique2(arr)); //(13) [1, "a", "true", true, 15, false, 1, {…}, null, NaN, NaN, "NaN", 0, "a", {…}, undefined]
function arr_unique5(arr){ return arr.filter((val,index,item)=>{ return item.indexOf(val) === index; }); } arr_unique5(arr); // (12) [1, "true", true, 15, false, undefined, null, "NaN", 0, "a", {…}, {…}]
function MaoPaoSort(arr){ for(var i = 0;i<arr.length-1;i++) { for(var j = 0;j<arr.length-i-1;j++){ if(arr[j]>arr[j+1]){ //把大的数字放到后面 var str = arr[j]; arr[j] = arr[j+1]; arr[j+1] = str; } } } } var arr = [3,5,1,2,7,8,4,5,3,4]; //console.log(arr);[3,5,1,2,7,8,4,5,3,4]; MaoPaoSort(arr); //console.log(arr);[1, 2, 3, 3, 4, 4, 5, 5, 7, 8]
function InsertSort(arr) { let len = arr.length; let preIndex, current; for (let i = 1; i < len; i++) { preIndex = i - 1; current = arr[i]; while (preIndex >= 0 && current < arr[preIndex]) { arr[preIndex + 1] = arr[preIndex]; preIndex--; } arr[preIndex + 1] = current; } return arr; } var arr = [3,5,7,1,4,56,12,78,25,0,9,8,42,37]; InsertSort(arr);