为什么要推出Vue3
vue这种级别的框架在进行主版本升级时,并不是一蹴而就的,而是需要经过长期的调研并论证出了新方案的可行性后才会做出的决定,其中涉及到了很多方面的因素,下边我罗列出了对于我们使用者来说更关心的一些因素
- 随着ES2015标准的发布,Javascript得到了重大改进,其中Proxy这个特性对于vue尤其重要,因为在Vue2中,响应式的数据原理是通过 Object.defineProperty 这个api遍历用户传递的data对象属性,从而将其转为getter和setter。这样的方式存在三个问题:
- 由于需要遍历data对象上所有属性,所以如果data对象的属性结构嵌套很深,那么就会存在性能问题
- 由于需要遍历属性的原因,所以这里就需要预先知道对象上有哪些属性,才能将其转为getter和setter。因此在Vue2中无法将data新增的属性转为响应式,只能通过vue提供的Vue.set或者this.$set向data中嵌套的对象新增响应式属性,然而这种方式并不能添加根级别的响应式属性
- 不能通过下标或者length属性响应式地改变数组,而是必须得用数组的方法:push、pop、shift、unshift、splice来响应式地改变数组
Proxy这个特性就可以很好地解决上述三个问题,因为proxy实际就是代理了整个对象的操作,代理的操作如下:
- 属性访问
- 属性设置
- 属性新增
- 属性删除
Proxy这个特性我认为其实是从更高维度对属性进行拦截,而不用关心对象结构实际是什么形式,可以很大程度降低因属性操作所带来的心智负担。
由于Vue2一开始设计时,并未考虑类型系统的重要性,所以导致了Vue2对于Typescript的支持不是很友好,为支持Typescript目前较为常见的方案是使用vue-classs-componet或者vue-property-decorator。在Vue3中,源码就是使用Typescript编写的,所以天生就对Typescript友好支持,因此Typescript相关的第三方库也可以做到更好的支持。
Vue3相对Vue2来说,有更小的体积。Vue3中是通过将大多数全局API和内部工具函数移动到module.exports属性上实现这一点。这允许现代模式下的module bundler能够静态地分析模块依赖关系,并删除未使用的的代码。框架中有些部分永远不会被“树抖动”(这部分的代码永远不会从框架中删除),因为它们对任何类型的应用程序都是必不可少的,这些不可缺少的部分称为基线大小。尽管增加了许多新特性,但Vue3被压缩后的基线大小约为10KB,不到Vue2的一半
为什么要使用Vue3
Vue3带来了很多新的特性:
- Performance:性能比Vue2快1.2~2倍
- Tree shaking support:支持按需编译,体积更小
- Composition API:组合API,类似React Hooks
- Custom Renderer API:暴露了自定义渲染API
- Fragment,Teleport(Protal),Suspense:新增三个组件
- Better TypeScript support:更好的支持TS
其中很大一部分的新特性都是针对Vue2中使用的痛点提出的,下文以Composition API为例,说明Vue3带给我们的好处
在Vue2中,我们通常是通过option的方式书写组件。根据Vue2给我们提供的选项,诸如components,data,watch,mixin来书写业务逻辑。这样的好处是同一类的选项都在一个option下,但是坏处也非常明显:实现同一个业务功能逻辑的代码被这种option的书写方式强行割裂开了。这样导致的结果就是在开发或者维护一个功能时,可能需要跳转很多地方才能将其梳理清楚,这样会导致心智负担急剧增加。
在Vue3中,使用Composition API就可以很好地将同一段逻辑代码放置在一起,很大程度降低了心智负担。下边引用一张图以便直观感受下在实际开发中,同一个业务功能逻辑代码在Vue2与Vue3中的分布情况
利用Composition API可以将复用的逻辑代码封装起来,供其他组件使用,从而大大降低代码书写量。这里的思想跟react的hooks非常相似,只不过并没有react使用hooks的那些限制:
- 不要在循环,条件或嵌套函数中调用 Hook, 确保总是在你的 React 函数的最顶层调用他们。
- 不要在普通的 JavaScript 函数中调用 Hook。
将Composition API与Vue2中的mixin进行对比,虽然二者都可以实现逻辑复用的功能,但是mixin带来的副作用是众所周知的:
- mixin是一个黑盒,使用的时候无法直接知道其中暴露了哪些功能或者属性
- 正因为mixin是黑盒,所以很容易造成命名上的冲突,从而引发极难排查的bug
利用Composition API,就可以很好地解决该类问题。因为它会显性地暴露出其中的功能和属性,这样在使用时就能很清晰地追溯属性与方法的来源,从而可以避免问题的产生
结语
这篇文章我只是简单地阐述了Vue3带来的新特性以及带给我们开发上的便利,更多的东西还是需要我们在实际项目中去挖掘,这里可以援引一句话:纸上得来终觉浅,绝知此事要躬行