我喜欢带着问题去学习一个东西。所以,在开始看这篇文章开始之前,我先问大家一个问题。
- vuejs解决了什么问题?
这里所说的解决的问题是和以前的开发模式比,在没有此类mvvm框架之前,我们主要是通过jquery来开发。通过jquery来开发个人感觉有两点不够友好
- 开发者需要过多的关注于如何操作dom
- 在涉及到频繁的操作dom时,性能不够好。我们比较难做到如何精准定位到真正需要更新的dom和何时去更新
针对第二点我们来做个说明
假设我们有如下情景,在一个页面中,一个变量的改变会引起页面中其余多个变量的改变并要在页面中体现出来。在以前的开发模式下,我们需要手动的改变那多个变量。并且在有些场景下我们很难做到精准定位。
vuejs是渐进式框架
所谓渐进式框架,我们可以从如下两个方面来理解
- 你可以根据你自己项目的需求有选择性的去采用自己所需的技术栈。例如你的项目不涉及到路由或者复杂的状态管理,那么你完全可以不用vue-router 和 vuex
- 假设你有个项目是通过html写的,但是现在某块内容需要设计到比较复杂的dom和数据之间的交互,那么你可以只对这一块内容采用vuejs
vuejs 整体运行过程

这种图从整体上描述了vuejs的运行机制,我们今天主要对其中的patch过程进行分析
在理解patch过程之前我们先来了解下如下几个概念
- 什么是DOM
- 什么是虚拟DOM
- 加入虚拟DOM的作用是什么
- 虚拟dom如何和真实的dom关联起来
- 加入虚拟dom的好处
什么是DOM
文档对象模型(DOM)是HTML 和 XML 文档的编程接口。它提供了对文档的结构化的表述,并定义了一种方式可以使从程序中对该结构进行访问,从而改变文档的结构,样式和内容。DOM将文档解析为一个由节点和对象(包含属性和方法的对象)组成的结构集合。简言之,它会将web页面和脚本或程序语言连接起来

什么是虚拟DOM
用js对象来描述dom节点比较重要的信息(tag类别,子节点,父节点等等)
对比下通过通过直接操作dom 和 通过虚拟dom 开发的区别

我们可以看到当采用了vuejs以后,我们不需要直接关心数据和dom是如何关联的
虚拟dom如何和真实的dom关联起来
虚拟节点会有elm属性保存该虚拟节点所对应的真实节点(mounted)
虚拟dom有什么好处呢?
- 开发者不需要关心如何操作dom
- 让跨平台成为了可能
- 可以增加patch过程,提高性能
- 让我们的开发模式变成了只需要关心数据
如果让你设计diff算法,你该如何设计?
通过上述分析,我们知道vuejs在需要更新页面的时候会先对比虚拟节点,然后再更新真实dom,所以我们可以考虑如下几个点
- 能复用的尽量复用旧元素
- 尽可能的一次性删除不需要的旧节点
- 尽可能的一次性增加新的节点
我们通过几个例子来分析

changeName 新老节点对比

从虚拟节点树上可以看出,我们只是从 bob 改变成了 alice 其他的都可以复用
changeIsNeedShowInterests 新老节点对比

我们可以看到这次我们只需要删除ul就行,别的都能复用
changeInterests 新老节点对比

这次只需要将第一个li元素的文本改和新增加一个li元素就行
vuejs采用了双索引和层级遍历

key的作用?
1:方便快速判断新老节点是否相等
2:方便快速确定新节点在老节点里是否存在