当前位置: 首页 > wzjs >正文

杭州市建设银行网站高平网站优化公司

杭州市建设银行网站,高平网站优化公司,泉州市做网站优化,网站title的写法‌双端比较算法是Vue中用于高效比较新旧VNode子节点的一种策略‌。该算法的核心思想是,通过从新旧VNode子节点的两端开始比较,逐步向中间靠拢,以找到最小的差异并据此更新DOM。以下是双端比较算法的大致流程: ‌初始化指针‌&…

‌双端比较算法是Vue中用于高效比较新旧VNode子节点的一种策略‌。该算法的核心思想是,通过从新旧VNode子节点的两端开始比较,逐步向中间靠拢,以找到最小的差异并据此更新DOM。以下是双端比较算法的大致流程:

  • ‌初始化指针‌:设置四个指针,分别指向新旧VNode子节点的开始和结束位置。
  • 首尾比较‌:首先比较新旧VNode子节点的首尾元素。如果首尾元素相同,则直接复用,并移动相应的指针。
  • 交叉比较‌:如果首尾元素不同,则进行交叉比较,即比较旧节点的末尾和新节点的开头,以及旧节点的开头和新节点的末尾。
  • 移动指针‌:根据比较结果,移动指针以缩小比较范围。如果找到匹配的节点,则复用该节点,并根据匹配情况调整指针位置。
  • 结束条件‌:当任一节点的开始指针超过结束指针时,表明已经遍历完至少一个节点的所有子节点,此时结束比较。
    在这里插入图片描述

这里以伪代码的形式进行展示,其中oldChildren是旧的虚拟DOM,newChildren是新的虚拟DOM,通过patch来更新真实的DOM结构

function diff(oldChildren, newChildren) {let oldStartIdx = 0              // 旧子节点起始指针let oldEndIdx = oldChildren.length - 1  // 旧子节点结束指针let newStartIdx = 0              // 新子节点起始指针let newEndIdx = newChildren.length - 1  // 新子节点结束指针while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {// 获取当前指针指向的节点let oldStartVNode = oldChildren[oldStartIdx]let oldEndVNode = oldChildren[oldEndIdx]let newStartVNode = newChildren[newStartIdx]let newEndVNode = newChildren[newEndIdx]// --- 四种比较场景 ---// 1. 旧头 vs 新头(复用)if (oldStartVNode.key === newStartVNode.key) {patch(oldStartVNode, newStartVNode)  // 更新节点属性oldStartIdx++newStartIdx++}// 2. 旧尾 vs 新尾(复用)else if (oldEndVNode.key === newEndVNode.key) {patch(oldEndVNode, newEndVNode)oldEndIdx--newEndIdx--}// 3. 旧头 vs 新尾(移动:旧头移动到旧尾之后)else if (oldStartVNode.key === newEndVNode.key) {patch(oldStartVNode, newEndVNode)insert(oldStartVNode.el, parentEl, oldEndVNode.el.nextSibling)  // DOM移动操作oldStartIdx++newEndIdx--}// 4. 旧尾 vs 新头(移动:旧尾移动到旧头之前)else if (oldEndVNode.key === newStartVNode.key) {patch(oldEndVNode, newStartVNode)insert(oldEndVNode.el, parentEl, oldStartVNode.el)oldEndIdx--newStartIdx++}// --- 如果四种场景都不匹配 ---else {// 尝试在旧子节点中查找与 newStartVNode 匹配的节点let foundIdx = oldChildren.findIndex(node => node.key === newStartVNode.key)if (foundIdx !== -1) {// 找到可复用的旧节点,移动它到旧头之前let foundVNode = oldChildren[foundIdx]patch(foundVNode, newStartVNode)insert(foundVNode.el, parentEl, oldStartVNode.el)oldChildren[foundIdx] = undefined  // 标记该位置已处理} else {// 没有可复用节点,创建新节点插入到旧头之前createEl(newStartVNode)insert(newStartVNode.el, parentEl, oldStartVNode.el)}newStartIdx++}}// --- 处理剩余节点 ---// 1. 如果旧子节点遍历完毕,剩余新节点需要新增if (oldStartIdx > oldEndIdx && newStartIdx <= newEndIdx) {for (let i = newStartIdx; i <= newEndIdx; i++) {createEl(newChildren[i])insert(newChildren[i].el, parentEl, oldChildren[oldStartIdx]?.el || null)}}// 2. 如果新子节点遍历完毕,剩余旧节点需要删除else if (newStartIdx > newEndIdx && oldStartIdx <= oldEndIdx) {for (let i = oldStartIdx; i <= oldEndIdx; i++) {remove(oldChildren[i].el)}}
}

其中patch函数的核心作用是 ‌复用已有的真实 DOM 节点,并用新虚拟节点(VNode)的属性更新对应的真实 DOM

问题1:patch 函数的具体更新逻辑
‌(1)更新属性(props)‌
‌新增/修改属性‌:将新 VNode 的 class、style、id、自定义属性等同步到真实 DOM。
‌删除旧属性‌:移除新 VNode 中不存在的旧属性。

// 伪代码示例:更新 class
if (newVNode.class !== oldVNode.class) {el.className = newVNode.class;
}

‌(2)更新事件监听器‌
‌绑定新事件‌:若新 VNode 有事件(如 @click),则绑定到真实 DOM。
‌解绑旧事件‌:若旧事件不存在于新 VNode 中,则移除。

// 伪代码示例:更新事件
if (newVNode.onClick !== oldVNode.onClick) {el.removeEventListener('click', oldVNode.onClick);el.addEventListener('click', newVNode.onClick);
}

‌(3)更新子节点‌
递归对比子节点,触发子树的 Diff 算法:

// 伪代码:递归更新子节点
if (newVNode.children && oldVNode.children) {updateChildren(el, oldVNode.children, newVNode.children);
}

‌(4)更新文本内容‌
若节点是文本节点,直接更新文本:

if (newVNode.text !== oldVNode.text) {el.textContent = newVNode.text;
}

示例说明‌
假设新旧虚拟节点如下:

// 旧虚拟节点
oldVNode = {tag: 'div',class: 'old-class',onClick: oldHandler,children: [A, B]
};// 新虚拟节点
newVNode = {tag: 'div',class: 'new-class',onClick: newHandler,children: [B, A, C]
};

‌patch 函数的操作步骤‌:

  • ‌更新 class‌:将真实 DOM 的 class 从 old-class 改为 new-class。
  • ‌更新事件‌:解绑旧的oldHandler,绑定新的 newHandler。
  • ‌更新子节点‌:触发子节点的双端 Diff 算法,复用 B 和 A,新增 C,可能移动节点位置。

问题:‌在更新过程中旧节点数量是否变化?‌
‌旧虚拟节点(oldChildren)的数量不会改变‌,但‌真实 DOM 中子节点数量会增加‌:

‌(1)新旧虚拟节点的数量是固定的‌
‌旧节点列表(oldChildren)‌:在 Diff 过程中是固定的,长度由初始渲染时决定。
‌新节点列表(newChildren)‌:是目标结构,算法需将真实 DOM 更新到该结构。
无论是否插入新节点,oldChildren 和 newChildren 的虚拟节点数量是固定的,不会动态增减。

‌(2)真实 DOM 的子节点数量会暂时增加‌
‌插入新节点的本质‌:在真实 DOM 中新增了一个节点(newStartVNode.el)。
‌旧节点的存在性‌:未被复用的旧节点仍然存在于真实 DOM 中,直到被明确删除。
此时真实 DOM 的子节点数量为:
旧节点数量 + 新增节点数量 - 已删除的旧节点数量。

‌2. 示例场景
假设初始状态为(这里是虚拟DOM):

oldChildren: [A, B, C]  // 旧节点数量为 3
newChildren: [D, A, B]  // 新节点数量为 3

执行流程如下:

  • ‌处理新头节点 D‌:
  • 在 oldChildren 中未找到可复用的节点。 ‌创建新节点 D‌,并插入到旧头节点 A 之前。
  • 此时真实 DOM 结构为 [D, A, B, C](4 个节点)。

‌继续 Diff 后续节点‌:

  • 新头指针后移(newStartIdx++),处理下一个新节点 A。 发现 A 可复用旧头节点,移动并更新指针。
  • 最终清理未处理的旧节点‌: 新节点处理完毕后,剩余的旧节点 C 会被删除。 ‌最终真实 DOM 结构‌:[D, A, B](与新节点数量一致)。
http://www.dtcms.com/wzjs/254020.html

相关文章:

  • 电子商务网站建设相关职位网址seo分析
  • 网站分页导航网络营销专业就业方向
  • 彩票销信 网站怎么做网店seo排名优化
  • 网站建设 阿里免费建设个人网站
  • 怎么做微信电影网站seo技术培训学校
  • 做淘客的网站关键词有哪些产品优化是什么意思
  • 高中学校网站模板北京官网优化公司
  • 珠海建网站专业公司国际新闻最新消息今天 新闻
  • 网站管理机制建设情况完美日记网络营销策划书
  • 服饰东莞网站建设搜索引擎推广与优化
  • 毕业设计网站开发选题依据2023年6月份又封城了
  • 垂直网站内容建设廊坊百度提升优化
  • 怎样手机网站建设全网营销
  • 这两天发生的重大新闻金华关键词优化平台
  • 网站建设技术发展趋势预测网络营销做得好的公司
  • 免费个人网站下载百度联系电话
  • 自适应网站模板怎么做推广一次多少钱
  • 网站白名单 是什么百度小说排行榜
  • 郑州汉狮做网站的大公司怎么在平台上做推广
  • 网站建设问题及解决办法seo顾问咨询
  • 如何形容一个网站做的好惠州seo网站推广
  • 开通网站流程网络营销工具和方法
  • 做房地产一级市场的看什么网站农产品网络营销方案
  • 张云网站建设如何让百度收录网址
  • 免费商业网站模板seo诊断服务
  • iis 建立默认网站万网域名注册流程
  • 网站建设熊掌号上海百度推广排名优化
  • 黄南北京网站建设2022年度关键词
  • 网站公司动态做不了怎么办为什么外包会是简历污点
  • 做网站编程的电脑配置杭州网站建设方案优化