likes
comments
collection
share

Vue2的三大缺陷及Vue3的优势

作者站长头像
站长
· 阅读数 19

在面试过程中,经常会被问到这类问题:Vue 2有什么缺点,Vue 3 的优势是什么?

今天来梳理下Vue2的缺陷及Vue3的优势。

Object.defineProperty并不是真正的代理

Vue2 响应式并不是真正意义上的代理,而是基于 Object.defineProperty() 实现的。

对于 Object.defineProperty() 只是对某个属性进行拦截,所以有很多缺陷,比如:它只能对对象上已经存在的数据才能监听,新增的属性没有响应式。

因此,Vue3放弃了Object.defineProperty,采用ProxyProxy 才是真正的"代理"

怎么理解这两者的区别呢?

我们首先看 defineProperty 这个 API:

Object.defineProperty(obj, 'title', {
  get() {},
  set() {},
})

当项目里读取 obj.title和修改 obj.title的时候被 defineProperty 拦截,但 defineProperty 对不存在的属性无法拦截,所以 Vue2 中所有数据必须要在 data 里声明

而且,如果 title 是一个数组的时候,对数组的操作,并不会改变 obj.title 的指向,虽然我们可以通过拦截.push 等操作实现部分功能,但是对数组的长度的修改等操作还是无法实现拦截,所以还需要额外的 $set 等 API。

Proxy 这个 API 就是真正的代理了,我们先看它的用法:

new Proxy(obj, {
  get() { },
  set() { },
})

虽然 Proxy 拦截 obj 这个数据,但 obj 具体是什么属性,Proxy 则不关心,统一都拦截了。

而且 Proxy 还可以监听更多的数据格式,比如 Set、Map,这是 Vue2 做不到的。

当然,Proxy 存在一些兼容性问题,这也是为什么 Vue3 不兼容 IE11 以下的浏览器的原因,还好现在 IE 用的人不多了。

代码耦合,跨端开发难度大

Vue2引入了虚拟 DOM,这让我们多了一个用 JSON 来描述网页的工具,并且让虚拟 DOM 这个技术脱离了 Web 的限制。因此,虚拟 DOM 在小程序,客户端等跨端领域大放异彩。

但是,Vue2主要用在浏览器开发,它在源代码中是直接执行浏览器 API 的。但这样就会在 Vue2 的跨端方案中带来问题,比如利用Vue2搞出了weex开发 App 应用,在源码中单独维护了一个weex的文件夹,用来专门生成 App 平台对应的界面和逻辑。

如果现在要使用Vue2开发小程序或者客户端,就需要复制一份全部 Vue 的代码,把浏览器 API 换成客户端或者小程序的

比如 mpvue 就是这么做的,但是 Vue 后续的更新就很难享受到。

上面的问题就是Vue2 内部所有的模块都是揉在一起的,这样做会导致不好扩展的问题

Vue3 是怎么解决这个问题的呢?

那就是拆包,使用最近流行的 monorepo 管理方式,响应式、编译和运行时全部独立了,变成下图所示的模样:

Vue2的三大缺陷及Vue3的优势

可以看到,渲染的逻辑拆成了平台无关渲染逻辑和浏览器渲染 API 两部分

当用 Vue3 开发小程序以及开发客户端的时候,就不用全部 fork Vue 的代码,只需要实现平台的渲染逻辑就可以。

Vue2的三大缺陷及Vue3的优势

另外,在 Vue3 的组织架构中,响应式独立了出来。而 Vue2 的响应式只服务于 Vue,Vue3 的响应式就和 Vue 解耦了,你甚至可以在 Node.js 和 React 中使用响应式

Option API三大问题

Options API 的写法有几个很严重的问题:

  1. 由于所有数据都挂载在 this 之上,因而 Options API 的写法对 TypeScript 的类型推导很不友好,并且这样也不好做 Tree-shaking 清理代码。

  2. 新增功能基本都得修改 datamethod 等配置,并且代码上 300 行之后,会经常上下反复横跳,开发很痛苦。

  3. 代码不好复用,Vue2 的组件很难抽离通用逻辑,只能使用 mixin,还会带来命名冲突的问题。

Vue3 使用了 Composition API 来解决上面这些问题,Composition API也叫组合 API

Composition API 对我们开发 Vue 项目起到了巨大的帮助。

下面这个示例图很好地说明了问题:每一个功能模块的代码颜色一样,左边是 Options API,一个功能的代码零散的分布在 data,methods 等配置内,维护起来很麻烦,而右边的 Compositon API 就不一样了,每个功能模块都在一起维护,同时可以抽离出来单独维护。

Vue2的三大缺陷及Vue3的优势

Vue3其他优势

使用 TypeScript 重构

使用 TypeScript 主要有两个好处:

  1. 类型系统带来了更方便的提示;
  2. 类型系统让代码更健壮。
interface Person {
    name: string;
    age: number;
}
let me:Person = {
  name:'小米',
  age:18
}

me.age = '12' // 报错

定义一个类型 Person,里面的变量 name 是字符串类型,变量 age 是数字类型,违反这个设置的数据就报错。

这在多人协同和长期维护的项目里带来的收益是巨大的,因为这样可以使错误的代码在编译阶段就被发现,从而避免程序上线运行后才发现异常报错

Vue3 提供了新的组件

Vue3 还内置了 FragmentTeleportSuspense 三个新组件。

  • Fragment: Vue 3 组件不再要求有一个唯一的根节点,清除了很多无用的占位 div
  • Teleport: 允许组件渲染在别的元素内,主要开发弹窗组件的时候特别有用。
  • Suspense: 异步组件,更方便开发有异步请求的组件。

新一代工程化工具 Vite

Vite 的竞品是 WebpackVite的兴起是现代浏览器已经默认支持了 ES6 的 import 语法,Vite 就是基于这个原理来实现的。

具体来说,在调试环境下,我们不需要全部打包,只是把你首页依赖的文件,依次通过网络请求去获取,整个开发体验得到巨大提升,做到了复杂项目的秒级调试和热更新。

Vue2的三大缺陷及Vue3的优势

而传统的Webpack要把所有的依赖打包后,才能开始调试:

Vue2的三大缺陷及Vue3的优势

按照现在的趋势看,Vite使用率超过 Webpack 是早晚的事。

总结

Vue3针对Vue2出现的问题都进行了针对性的改进,主要有如下几个方面:

  1. 响应式原理:使用Proxy取代Object.defineProperty()
  2. 代码组织方式:采用了Compositon API取代Option API
  3. 工程化工具:采用Vite代替Webpack
转载自:https://juejin.cn/post/7243607462008078373
评论
请登录