Vue.js 从 1.x 到 2.0 版本,最大的升级就是引入了虚拟 DOM 的概念,它为后续做服务端渲染以及跨端框架 Weex 提供了基础。

Vue.js 2.x 发展了很久,现在周边的生态设施都已经非常完善了,而且对于 Vue.js 用户而言,它几乎满足了我们日常开发的所有需求。在迭代 2.x 版本的过程中,小右发现了很多需要解决的痛点,比如源码自身的维护性,数据量大后带来的渲染和更新的性能问题,一些想舍弃但为了兼容一直保留的鸡肋 API 等;另外,小右还希望能给开发人员带来更好的编程体验,比如更好的 TypeScript 支持、更好的逻辑复用实践等,所以他希望能从源码、性能和语法 API 三个大的方面优化框架。

那么接下来,我们就一起来看一下 Vue.js 3.0 具体做了哪些优化, 了解Vue.js 3.0的升级给我们开发带来什么收益。

一、源码优化1更好的代码管理方式:monorepo>>>>

Vue.js 2.x

源码托管在 src 目录

src
├── compiler        # 编译相关
├── core            # 核心代码
├── platforms       # 不同平台的支持
├── server          # 服务端渲染
├── sfc             # .vue 文件解析
├── shared          # 共享代码

>>>>

Vue.js 3.0

monorepo 把这些模块拆分到不同的目录中,每个模块有各自的API类型定义和测试。这样使得模块拆分更细化,职责划分更明确,模块之间的依赖关系也更加明确,开发人员也更容易阅读、理解和更改所有模块源码,提高代码的可维护性。

@vue
├── compiler-core
│   ├── LICENSE
│   ├── README.md
│   ├── dist
│   │   ├── compiler-core.cjs.js
│   │   ├── compiler-core.cjs.prod.js
│   │   ├── compiler-core.d.ts
│   │   └── compiler-core.esm-bundler.js
│   ├── index.js
│   └── package.json
├── compiler-dom
│   …
├── reactivity
│   …
├── runtime-core
│   …
├── runtime-dom
│   …
└── shared
   …

2有类型的 JavaScript:TypeScript>>>>

Vue.js 2.x

使用Flow做类型检查,Flow 是 Facebook 出品的 JavaScript 静态类型检查工具,它可以以非常小的成本对已有的 JavaScript 代码迁入,非常灵活。但是Flow 对于一些复杂场景类型的检查,支持得并不好。

>>>>

Vue.js 3.0

使用 TypeScript 重构了整个项目。TypeScript提供了更好的类型检查,能支持复杂的类型推导。

二、性能优化1源码体积优化>>>>

Vue.js 3.0

移除一些冷门的 feature(比如 filter、inline-template 等);

引入 tree-shaking 的技术,减少打包体积;

2数据劫持优化>>>>

Vue.js 2.x

Vue.js 2.x是采用数据劫持结合发布者-订阅者模式的方式来达到数据响应效果的。大体思路参考下图。(详细原理自行学习,哈哈)

Vue.js 2.x 内部是通过 Object.defineProperty 这个 API 去劫持数据的 getter 和 setter,具体是这样的:

Object.defineProperty(data, 'a',{  get(){    // track  },  set(){    // trigger  }})

但这个 API 有一些缺陷:

它必须预先知道要拦截的 key 是什么,所以它并不能检测对象属性的添加和删除。尽管 Vue.js 为了解决这个问题提供了 $set 和 $delete 实例方法;

对于嵌套层级较深的对象,如果要劫持它内部深层次的对象变化,就需要递归遍历这个对象,执行 Object.defineProperty 把每一层对象数据都变成响应式的。如果我们定义的响应式数据过于复杂,这就会有相当大的性能损耗;

>>>>

Vue.js 3.0

为了解决上述 2 个问题,Vue.js 3.0 使用了 Proxy API 做数据劫持,它的内部是这样的:

observed = new Proxy(data, {  get() {    // track  },  set() {    // trigger  }})

使用了 Proxy API 做数据劫持,它劫持的是整个对象,对于对象的属性的增加和删除都能检测到。

Proxy API 并不能监听到内部深层次的对象变化,因此 Vue.js 3.0 的处理方式是在 getter 中去递归响应式,这样的好处是真正访问到的内部对象才会变成响应式,而不是无脑递归,这样无疑也在很大程度上提升了性能,我会在后面分析响应式章节详细介绍它的具体实现原理 。

3编译优化>>>>

Vue.js 2.x

通过数据劫持和依赖收集,Vue.js 2.x 的数据更新并触发重新渲染的粒度是组件级的,虽然 Vue 能保证触发更新的组件最小化,但在单个组件内部依然需要遍历该组件的整个 vnode 树。这就会导致 vnode 的性能跟模版大小正相关,跟动态节点的数量无关,当一些组件的整个模版内只有少量动态节点时,这些遍历都是性能的浪费。

>>>>

Vue.js 3.0

通过编译阶段对静态模板的分析,编译生成了 Block tree。Block tree 是一个将模版基于动态节点指令切割的嵌套区块,每个区块内部的节点结构是固定的,而且每个区块只需要以一个 Array 来追踪自身包含的动态节点。借助 Block tree,Vue.js 将 vnode 更新性能由与模版整体大小相关提升为与动态内容的数量相关。

三、语法 API 优化1逻辑组织优化>>>>

Vue.js 2.x

在 Vue.js 2.x 版本中,编写组件本质就是在编写一个“包含了描述组件选项的对象”,我们把它称为 Options API。Options API 的设计是按照 methods、computed、data、props 这些不同的选项进行分类。和一个逻辑点相关的代码可能写在多个Option里,非常分散,如果需要修改一个逻辑点,就需要在单个文件中不断切换和寻找。

>>>>

Vue.js 3.0

Vue.js 3.0 提供了一种新的 API:Composition API,它有一个很好的机制去解决这样的问题,就是将某个逻辑关注点相关的代码全都放在一个函数里,这样当需要修改一个功能时,就不再需要在文件中跳来跳去。

2逻辑复用优化>>>>

Vue.js 2.x

我们通常会用 mixins 去复用逻辑。使用单个 mixin 似乎问题不大,但是当我们一个组件混入大量不同的 mixins 的时候,会存在两个非常明显的问题:命名冲突和数据来源不清晰。

每个 mixin 都可以定义自己的 props、data,它们之间是无感的,所以很容易定义相同的变量,导致命名冲突;

对组件而言,如果模板中使用不在当前组件中定义的变量,那么就会不太容易知道这些变量在哪里定义的,这就是数据来源不清晰;

>>>>

Vue.js 3.0

使用 hook 函数,整个数据来源清晰了,也不会出现命名冲突的问题。

3更好的类型支持

因为它们都是一些函数,在调用函数时,自然所有的类型就被推导出来了。不像 Options API 所有的东西使用 this。

4tree-shaking 友好

tree-shaking有一个两个要求(对tree-shaking不熟的,还是自行去学习,哈哈):

必须是import导入。

是必须是单个函数或常量导出

>>>>

Vue.js 2.x

直接导出的是整个vue实例,如果我们只是简单的用某一些功能的话就有点累赘。

>>>>

Vue.js 3.0

用到的函数可以通过import声明,对“按需加载”有更好的支持。

注意

Composition API 属于 API 的增强,它并不是 Vue.js 3.0 组件开发的范式,如果组件足够简单,可以使用 Options API。

本文主要总结了 Vue.js 3.0 升级做了几个方面的优化,以及为什么会需要这些优化。希望学习完后我们也可以像小右一样去审视自己的工作,有哪些痛点,找到可以改进和努力的方向并实施,只有这样才能够不断提升自己的能力,工作上也会有不错的产出。

资料参考来源:

黄轶老师--《Vue.js 3.0 核心源码解析》课程

感谢阅读~~扫码关注我们前端麻辣烫仙女都在看点点点,赞和在看都在这儿!

vue 3.0和2.0区别_一文看懂 Vue.js 3.0 的优化相关推荐

  1. python开发前端后端区别_一文看懂前端和后端开发

    作为一名开发者,你可能会想:2019 年最好的软件开发技术和编程语言会是什么?它们又是如何被应用在软件开发当中的?如果你在思考这个问题,那就来对地方了.这篇文章将对前端和后端开发技术做一个对比,先从基 ...

  2. 有源带阻和无源带阻的区别_一文看懂AOC有源光缆与DAC高速线缆的差异

    AOC有源光缆和DAC高速线缆都被用于数据中心短距离服务器互连及服务器与交换机互连,那么它们两者究竟有什么区别呢?下面易天光通信(ETU-LINK)就带你一起来了解下吧. 一.AOC有源光缆 VS D ...

  3. mesh和wifi中继的区别_一文看懂Mesh路由和无线中继的差异

    随着时代的发展,如今人们的生活与从前相比已经是有了天翻地覆的变化,就单单拿住房条件来说,20年还没有如今这么多的高楼大厦,人们的居住用房也基本上是矮层居民楼,户型也普遍较小,一家人住起来十分紧凑.如今 ...

  4. 怎么看电脑系统是win几_一文看懂arm架构和x86架构有什么区别

    一文看懂arm架构和x86架构有什么区别 本文主要介绍的是arm架构和x86架构的区别,首先介绍了ARM架构图,其次介绍了x86架构图,最后从性能.扩展能力.操作系统的兼容性.软件开发的方便性及可使用 ...

  5. angular 字符串转换成数字_一文看懂Python列表、元组和字符串操作

    好文推荐,转自CSDN,原作星辰StarDust,感觉写的比自己清晰-大江狗荐语. 序列 序列是具有索引和切片能力的集合. 列表.元组和字符串具有通过索引访问某个具体的值,或通过切片返回一段切片的能力 ...

  6. mysql删除分表键_一文看懂 MySQL 分区和分表,提高表增删改查效率

    原标题:一文看懂 MySQL 分区和分表,提高表增删改查效率 作者:冯帅,精通Oracle. MySQL. 擅长异构数据库数据同步及迁移.数据库的设计和调优,对高可用方案有深入研究. MySQL分区和 ...

  7. 天线巴伦制作和原理_一文看懂巴伦(功能原理、性能参数、基本类型)

    原标题:一文看懂巴伦(功能原理.性能参数.基本类型) 巴伦(英语为balun)为一种三端口器件,或者说是一种通过将匹配输入转换为差分输出而实现平衡传输线电路与不平衡传输线电路之间的连接的宽带射频传输线 ...

  8. java rest 序列化_一文看懂Java序列化

    一文看懂Java序列化 简介 首先我们看一下wiki上面对于序列化的解释. 序列化(serialization)在计算机科学的数据处理中,是指将数据结构或对象状态转换成可取用格式(例如存成文件,存于缓 ...

  9. 0宽字符加密_一文看懂异或加密,有动画演示呦

    应用程序保护是指单词和应用程序 什么是异或加密 在逻辑运算中,除了 与 或 非 这 3 种运算之外,还有一种运算运算叫做 异或(xor),符号记为 ^,异或运算简单来说就是 相同为 0,不同为 1, ...

最新文章

  1. QA:智能布线系统二十问
  2. 最近在北京做银行软件项目亲身感受小总结
  3. 使用putty在linux主机和windows主机之间拷贝文件(已测试可执行)
  4. bzoj 4570: [Scoi2016]妖怪 凸包
  5. Linux手机研发要过五大难关
  6. 算法面试题 java_【面试算法题】Java Stack 类的使用
  7. mysql里cis_CIS MySQL存储库表修复过程
  8. 高中数学基础-2.2.1 对数及对数的运算(下)
  9. 【ESP32_8266_WiFi (十四)】ESP8266多任务处理 – Ticker库使用说明
  10. Django数据库学习——定义用户模型(实例)
  11. 2018最新安卓面试大全(含BAT,网易,滴滴)----你面不上BAT的原因:面经宝典,都在这里啦
  12. 熔断器熔断时间标准_正确认识熔断器的熔断时间
  13. python爬虫采集京东商品评价
  14. INI 文件读取专用类
  15. 计算机网络知识详解之:TCP连接原理详解
  16. 豆瓣FM产品分析 | 纯粹极简的听歌APP
  17. 如何读关于设计模式的那几本书
  18. 极路由1s HC5661 编程器救砖教程
  19. Crazy Defense Heroes 如何冲入 GameFi 前 4?
  20. 【新闻传播学论文】微信公众平台新闻传播正负效应探索(节选)

热门文章

  1. android ge模拟器,在Android模拟器上的一些小陷阱
  2. Java使用ojdbc连接Oracle数据库时不能使用服务名连接的问题
  3. rust go java 性能_Java,Go和Rust之间的比较 - Dexter
  4. 查看redis版本_redis详细介绍
  5. three.js两个点给线条加宽度_108m2家里镶金线条,就是不一样,装出大宅范!太美了!晒晒...
  6. sqlserver执行更新语句失败报错42S22
  7. Cython——[FutureWarning: Cython directive ‘language_level’ not set, using 2 for now (Py2)]解决方案
  8. JavaScript——易班优课YOOC课群在线测试自动答题解决方案(二十一)禁止打开控制台解决方案
  9. 《IBM-PC汇编语言程序设计》(第2版)【沈美明 温冬婵】——自编解析与答案
  10. 《计算机网络》实验报告——常用网络命令