h 函数

1: h 函数: 

<body>
  <button>点击我改变DOM</button>
  <div id="container"></div>
</body>

1: 创建patch 函数
const patch = init([classModule, propsModule, styleModule, eventListenersModule]);

const vnode1 = h('ul', {}, [
   h('li', {}, 'A'),
   h('li', {}, 'B'),
   h('li', {}, 'C'),
   h('li', {}, 'D')
])

const vnode2 = h('ul', {}, [
   h('li', { key: 'A' }, 'A'),
   h('li', { key: 'B' }, 'B'),
   h('li', { key: 'C' }, 'C'),
   h('li', { key: 'D' }, 'D'),
   h('li', { key: 'E' }, 'E')
])

const container = docuent.getElementById('container');  // 获取元素节点
const btn= docuent.getElementById('button');  // 获取元素节点

patch(container, vnode1);   // 需要渲染的容器,  需要渲染的vnode 节点

// 点击按钮事件,   点击事件时, 将vnode1 改变为vnode2;  内部最小量更新
btn.onclick = function() {
  patch(vnode1, vnode2)
}

diff 算法中的patch函数是 重要的函数, 实现最小量更新;
v-for: 一定要加key 值, 否则就会全量更新。 key: 是唯一标识,算法效率会非常高效。
key: 就是实现最小量更新的, 提高算法效率。 (当然: key 很重要。key是这个节点的唯一标识, 告诉 diff算法, 在更改前后他们是同一DOM 节点)。

只会进行同层比较,  不会进行跨层比较。 即使是同一片虚拟节点, 但是跨层了,  精细化比较不会diff你。 而是暴力拆除旧的,  然后插入新的。 只要是父级节点改变, 所有的子级


只会进行同层比较,  不会进行跨层比较。

// 什么是同一个虚拟节点? 同一个虚拟节点 (就是选择器相同, 并且key值相同)
diff 算法是同层比较效率最高:  patch 函数;

分析 diff 算法:

patch 函数被调用: 判断vnode 是虚拟节点还是DOM 节点? 如果是DOM节点 将oldnode 包装为虚拟节点;

如果是虚拟节点 (oldnode 和 newnode 是不是同一个节点??)  ===> 如果不是暴力删除旧的, 插入新的 
 ===> 然后进行精细化比较。


如何判断新 旧DOM 为同一个节点: 就是有相同的选择器, 和相同的key值
sameVnode() 函数:

function sameVnode (vnode1: VNode, vnode2: VNode): boolean {
   return vnode1.key === vnode2.key && vnode1.sel === vnode2.sel
}

创建一个patch.js 文件夹

patch 函数
// 函数的功能非常简单, 就是把传入的5个参数组合成对象返回
let vnode (sel, data, children, text, elm) {
    return { sel, data, children, text, elm };
}

export default vnode;
--------------------------------------------------------------
创建元素节点   创建 createElement.js 文件
export default function(vnode, pivot) {
    console.log('目的就是虚拟节点', vonode, '插入到标杆', pivot, '前');
    创建一个DOM 节点, 这个节点是单一节点
    let domNode = document.createElement(vnode.sel);
    有子节点还是有文本??
    if(vnode.text != "" && (vnode.children == undefined || vnode.children.length ==0)) {
      // 它内部是文本
      domNode.innerText = vnode.text;
      // 将单一节点上树, 让标杆节点的父元素调用insertBefore 方法, 将新的单一节点插入到标签节点之前
     pivot.parentNode.insertBefore(domNode, pivot);
   }else if(Array.isArray(vnode.children) && vnode.children.length > 0) {
     //创建子节点
   }
}


import vnode form './vnode.js'   // 导入vnode 虚拟节点
  
const patch (oldVnode, newVnode) {
     // 判断传入的第一个参数, 是DOM 节点还是虚拟DOM 节点?
   if(oldVnode.sel == '' || oldVnode.sel == undefined) {
     // 说明传入的第一个参数是DOM 节点,  此时要包装为虚拟节点
     oldVnode = vnode(oldVnode.tagName.toLowerCase(), {}, [], underfined, oldVnode);

   }

   // oldVnode 和 newVnode 是不是同一个节点
   if(oldVnode.key == newVnode.key && oldVnode.sel == newVnode.sel) {
      '是同一个节点' ===> 进行精细化比较
   } else {
      '不是同一个节点, 暴力插入新的, 删除旧的'
   }
}

export default patch;  // 向外暴露patch 函数

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值