Vue,你好

75 阅读4分钟

为什么学习 Vue

  • Vue简单:简单到后端同学看看就会了。
  • Vue 在每个维度之间,做了非常好的权衡和取舍,算是一个非常中庸且优雅的框架,兼顾响应式、虚拟 DOM、运行时和编译优化。

其他框架特点:

  • React 注重数据不可变、虚拟 DOM 和运行时

  • Svelte 运行时都非常轻量级,侧重在于编译时的优化

  • Angular 则在抽象这个维度又走向一个极致,生来就是为了复杂项目。

前端三大框架

AngularJS 的诞生,引领了前端 MVVM模式的潮流。

MVVM模式:Model-View-ViewModel),在前端的场景下,把 Controller变成了 View-Model层,作为 ModelView的桥梁,Model 数据层和 View 视图层交给 View-Model 来同步。

阶段一:利用数据驱动页面

面临核心问题:数据发生变化后,怎么去通知页面更新。

来看下三大框架各自是怎么处理的?

Angular 1解决方案:就是最老套的脏检查

所谓的脏检查: 指的是 Angular 1 在对数据变化的检查上,遵循每次用户交互时都检查一次数据是否变化,有变化就去更新 DOM 这一方法。

这个方法看似简单粗暴,但算是数据驱动页面早期的实现,所以一经推出,就迅速占领了 MVVM 市场。

Vue 1 的解决方案:就是使用响应式。

  • 初始化的时候Watcher 监听了数据的每个属性。
  • 数据发生变化的时候,就能精确地知道数据的哪个 key 变了,去针对性修改对应的 DOM 即可。

React解决方案:通过虚拟 DOM ****计算出变化的数据,去进行精确的修改。

  • 初始化的时候,在浏览器 DOM 之上,搞了一个叫虚拟 DOM 的东西,也就是用一个 JavaScript 对象来描述整个 DOM 树。
  • 这个对象就像数据和实际 DOM 的一个缓存层,通过管理这个对象的变化,来减少对实际 DOM 的操作
  • 数据变化后,只能通过新老数据的计算 Diff 来得知数据的变化。
// 举个栗子:如下代码
<div id = "app">
    <p class = "item">Item1</p>
    <div class = "item">Item2</div>
</div>

// 对应 虚拟 DOM:
{
  tag: "div",
  attrs: {
    id: "app"
  },
  children: [
    {
      tag: "p",
      attrs: { className: "item" },
      children: ["Item1"]
    },
    {
      tag: "div",
      attrs: { className: "item" },
      children: ["Item2"]
    }
  ]
}

浏览器操作 DOM 一直都是性能杀手,而虚拟 DOM 的 Diff 的逻辑,又能够确保尽可能少的操作 DOM,这也是虚拟 DOM 驱动的框架性能一直比较优秀的原因之一。

Vue2 解决:响应式数据过多,内存占用过多问题

这时的 React面临主要问题:虚拟DOM树 过大,影响性能。

React 为了突破性能瓶颈,借鉴了操作系统时间分片的概念,引入了 Fiber 架构

就是把整个虚拟 DOM 树微观化,变成链表

然后利用浏览器的空闲时间计算 Diff。一旦浏览器有需求,可以把没计算完的任务放在一旁,把主进程控制权还给浏览器,等待浏览器下次空闲。

树形结构的 Diff 很难中断;右侧是把树形结构改造成了链表,遍历严格地按照子元素 -> 兄弟元素 -> 父元素的逻辑,随时可以中断和恢复 Diff 的计算过程。

为了解决 Vue 1 的问题在于响应式数据过多,这样会带来内存占用过多的问题。

Vue 2 引入虚拟 DOM 来解决响应式数据过多的问题。

这个解决方案使用虚拟 DOM 解决了响应式数据过多的内存占用问题,又良好地规避了 React 中虚拟 DOM 的问题, 还通过虚拟 DOM 给 Vue 带来了跨端的能力。

  • 响应式数据(推): 主动推送变化,组件之间变化
  • 虚拟DOM(拉): 被动计算数据的 Diff组件内部的数据变化

Vue3 在虚拟 DOM 的静态标记上做到了极致

Vue React区别:

  • React 的世界里只有 JSX,最终 JSX 都会在 Compiler 那一层。
  • Vue 的世界默认是 template,也就是语法是限定死的。

Tips:``Svelte 这种框架,没有虚拟 DOM 的库,直接把模板编译成原生 DOM,几乎没有 Runtime,所有的逻辑都在 Compiler 层优化,算是另外一个极致。