美文网首页
(三)Vue-Snabbdom

(三)Vue-Snabbdom

作者: JerrySi | 来源:发表于2022-02-27 14:30 被阅读0次

虚拟 DOM 的作用

  1. 维护视图和状态的关系
  2. 复杂视图情况下提升渲染性能
  3. 跨平台
    • 浏览器平台渲染DOM
    • 服务端渲染 SSR(Nuxt.js/Next.js)
    • 原生应用(Weex/React Native)
    • 小程序(mpvue/uni-app)等

Snabbdom

  1. Vue.js 2.x 内部使用的虚拟 DOM 就是改造的 Snabbdom •
  2. 大约 200 SLOC (single line of code) 3
  3. 通过模块可扩展
  4. 源码使用 TypeScript 开发 •
  5. 最快的 Virtual DOM 之一

导入 Snabbdom

  1. 安装 Snabbdom
    • npm intall snabbdom@2.1.0
  2. 导入 Snabbdom
    Snabbdom 的两个核心函数 init 和 h()
    • init() 是一个高阶函数,返回 patch()
    • h() 返回虚拟节点 VNode,这个函数我们在使用 Vue.js 的时候见过
  3. 文档中导入的方式


  4. 实际导入的方式
    parcel/webpack 4 不支持 package.json 中的 exports 字段


模块

模块的作用
  1. Snabbdom 的核心库并不能处理 DOM 元素的属性/样式/事件等, 可以通过注册 Snabbdom 默认提供的模块来实现
  2. Snabbdom 中的模块可以用来扩展 Snabbdom的功能
  3. Snabbdom 中的模块的实现是通过注册全局的钩子函数来实现的
官方提供的模块

•attributes
• props
• dataset
• class
• style
• eventlisteners

  1. 导入需要的模块
  2. init() 中注册模块
  3. h() 函数的第二个参数处使用模块

Snabbdom 的核心

  1. init() 设置模块,创建 patch() 函数
  2. 使用 h() 函数创建 JavaScript 对象(VNode)描述真实 DOM
  3. patch() 比较新旧两个 Vnode
  4. 把变化的内容更新到真实 DOM 树

patch 整体过程分析

• patch(oldVnode, newVnode)
• 把新节点中变化的内容渲染到真实 DOM,最后返回新节点作为下一次 处理的旧节点
• 对比新旧 VNode 是否相同节点(节点的 key 和 sel 相同)
• 如果不是相同节点,删除之前的内容,重新渲染
• 如果是相同节点,再判断新的 VNode 是否有 text,如果有并且和 oldVnode 的 text 不同,直接更新文本内容
• 如果新的 VNode 有 children,判断子节点是否有变化

Diff 算法

Snbbdom 根据 DOM 的特点对传统的diff算法做了优化
• DOM 操作时候很少会跨级别操作节点
• 只比较同级别的节点


执行过程

在对开始和结束节点比较的时候,总共有四种情况
• oldStartVnode / newStartVnode (旧开始节点 / 新开始节点)
• oldEndVnode / newEndVnode (旧结束节点 / 新结束节点)
• oldStartVnode / newEndVnode (旧开始节点 / 新结束节点)
• oldEndVnode / newStartVnode (旧结束节点 / 新开始节点)


开始和结束节点

如果新旧开始节点是 sameVnode (key 和 sel 相同)
• 调用 patchVnode() 对比和更新节点
• 把旧开始和新开始索引往后移动 oldStartIdx++ / newStartIdx++


旧开始节点 / 新结束节点

• 调用 patchVnode() 对比和更新节点
• 把 oldStartVnode 对应的 DOM 元素,移动到右边,更新索引
为什么要移动到右边?

旧结束节点 / 新开始节点

• 调用 patchVnode() 对比和更新节点
• 把 oldEndVnode 对应的 DOM 元素,移动到左边,更新索引
为什么要移动到左边?

非上述四种情况
  1. 遍历新节点,使用 newStartNode 的 key 在老节点数组中找相同节点
  2. 如果没有找到,说明 newStartNode 是新节点
    • 创建新节点对应的 DOM 元素,插入到 DOM 树中
  3. 如果找到了
    • 判断新节点和找到的老节点的 sel 选择器是否相同
    • 如果不相同,说明节点被修改了
    重新创建对应的 DOM 元素,插入到 DOM 树中
    • 如果相同,把 elmToMove 对应的 DOM 元素,移动到左边


循环结束

• 当老节点的所有子节点先遍历完 (oldStartIdx > oldEndIdx),循环结束
• 新节点的所有子节点先遍历完 (newStartIdx > newEndIdx),循环结束

  1. oldStartIdx > oldEndIdx
    如果老节点的数组先遍历完(oldStartIdx > oldEndIdx)
    • 说明新节点有剩余,把剩余节点批量插入到右边


  2. newStartIdx > newEndIdx
    如果新节点的数组先遍历完(newStartIdx > newEndIdx)
    • 说明老节点有剩余,把剩余节点批量删除


相关文章

  • (三)Vue-Snabbdom

    虚拟 DOM 的作用 维护视图和状态的关系 复杂视图情况下提升渲染性能 跨平台• 浏览器平台渲染DOM• 服务端渲...

  • 三.三

    越来越多的年轻孩子们开始写字,说自己的生活,欲望和野心。大概两年的日子,是一边默默消化符合这个时代的速成文学,一边...

  • 36/70 二三三三三三三

    上周看的电影叫做《羞羞的铁拳》,女主马丽,男主艾伦,开心麻花出品。想不起来是从什么时候开始关注麻花作品的。应该是从...

  • 三棍儿(三)

    再说强子,跟着老黄上完了三年初小,虽然再也没有捧奖状回来,成绩算还不错。上完了三年级就要去镇上的高小去上四...

  • 三A三Q

    1.请写出参加这次交流对自己触动最大,感受最深的内容。 我觉得在这次讲座期间我思考了很多,我觉得这些观念给了我很大...

  • 三少(三)

    我一听心中一凛,就见祥子眯缝着看着我,却是不再说话。突然感觉背后冷飕飕的,像是一股阴风吹来,我整个人都像要炸了开来...

  • 三妹妹(三)

    我们虽一母同胞,却在不同的环境中长大,有着迥然不同的价值观。 最早的一次冲突,我们都很隐忍,彼此...

  • 三就是三

    三就是三,哪有什么后来者居上,连那个三妻四妾的时代都知道“聘为妻,奔为妾”,但凡有点教养,ta的骄傲的不允许ta插...

  • 三婶(三)

    为病魔所胁迫,徘徊在这个世界边缘,一直坐在病床上背对别人低着头的三婶,寡言少语,却从未放弃过任何一丝生存的希望,积...

  • 山三(三)

    某天晩上,蝉鸣声更欢了,空气似乎停滞或者被人类抽光,进入“真空地带”,近乎窒息,没有一丝流动。太阳已经完全落山了,...

网友评论

      本文标题:(三)Vue-Snabbdom

      本文链接:https://www.haomeiwen.com/subject/hbrzlrtx.html