vue源码分析-diff算法核心原理

这一节,依然是深入剖析Vue源码系列,上几节内容介绍了Virtual DOM是Vue在渲染机制上做的优化,而渲染的核心在于数据变化时,如何高效的更新节点,这就是diff算法。由于源码中关于diff算法部分流程复杂,直接剖析每个流程不易于理解,所以这一节我们换一个思路,参考源码来手动实现一个简易版的diff算法。

之前讲到Vue在渲染机制的优化上,引入了Virtual DOM的概念,利用Virtual DOM描述一个真实的DOM,本质上是在JS和真实DOM之间架起了一层缓冲层。当我们通过大量的JS运算,并将最终结果反应到浏览器进行渲染时,Virtual DOM可以将多个改动合并成一个批量的操作,从而减少 dom 重排的次数,进而缩短了生成渲染树和绘制节点所花的时间,达到渲染优化的目的。之前的章节,我们简单的介绍了VueVnode的概念,以及创建Vnode渲染Vnode再到真实DOM的过程。如果有忘记流程的,可以参考前面的章节分析。

**从render函数到创建虚拟DOM,再到渲染真实节点,这一过程是完整的,也是容易理解的。然而引入虚拟DOM的核心不在这里,而在于当数据发生变化时,如何最优化数据变动到视图更新的过程。这一个过程才是Vnode更新视图的核心,也就是常说的diff算法。**下面跟着我来实现一个简易版的diff算法

8.1 创建基础类

代码编写过程会遇到很多基本类型的判断,第一步需要先将这些方法封装。

class Util {
   
  constructor() {
   }
  // 检测基础类型
  _isPrimitive(value) {
   
    return (typeof value === 'string' || typeof value === 'number' || typeof value === 'symbol' || typeof value === 'boolean')
  }
  // 判断值不为空
  _isDef(v) {
   
    return v !== undefined && v !== null
  }
}
// 工具类的使用
const util = new Util()

8.2 创建Vnode

Vnode这个类在之前章节已经分析过源码,本质上是用一个对象去描述一个真实的DOM元素,简易版关注点在于元素的tag标签,元素的属性集合data,元素的子节点children,text为元素的文本节点,简单的描述类如下:

class VNode {
   
  constructor(tag, data, children) {
   
    this.tag = tag;
    this.data = data;
    this.children = children;
    this.elm = ''
    // text属性用于标志Vnode节点没有其他子节点,只有纯文本
    this.text = util._isPrimitive(this.children) ? this.children : ''
  }
}

参考Vue3源码视频讲解:进入学习

8.3 模拟渲染过程

接下来需要创建另一个类模拟将render函数转换为Vnode,并将Vnode渲染为真实DOM的过程,我们将这个类定义为Vn,Vn具有两个基本的方法createVnode, createElement, 分别实现创建虚拟Vnode,和创建真实DOM的过程。

8.3.1 createVnode

createVnode模拟Vuerender函数的实现思路,目的是将数据转换为虚拟的Vnode,先看具体的使用和定义。

// index.html

<script src="diff.js">
<script>

// 创建Vnode

let createVnode = function() {
     let _c = vn.createVnode;  return _c('div', {
    attrs: {
    id: 'test' } }, arr.map(a => _c(a.tag, {
   }, a.text)))}

// 元素内容结构
let arr =   [{
       tag: 'i',    text: 2
  }, {
       tag: 'span',    text: 3
  }, {
       tag: 'strong',    text: 4
  }]
</script>



// diff.js
(function(global) {
   
  class Vn {
   
    constructor() 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值