前言:vue2是一个响应式驱动的、内置虚拟DOM、组件化,用在浏览器开发,并且有一个运行时把这些模块很好的管理起来的框架,vue2 能把这些模块很好的管理起来,看起来已经足够好了,不过vue2还是有缺陷的,所以后面才会升级迭代。
缺陷1:首页从维护的角度看,vue2 是使用Flow.js来做的类型校验,但是现在Flow.js已经停止维护了,整个社区都在全面使用TypeScript来构建基础库,vue 团队也不例外。
缺陷2:从社区二次开发难度来说,vue2 内部运行时,是直接执行浏览器API的,但这样就会在vue2 的跨端方案中带来问题,要么直接进入vue源码中,和vue一起维护,比如vue2 中你就能看到Weex的文件夹。要么是要直接改为复制一份全部vue代码,把浏览器API换成客户端或者小程序,比如mpvue就是这么做的,但是Vue后续的更新就很难享受到。
缺陷3:最后从普通开发者的角度来说,1.vue2 响应式并不是真正意义上的代理,而是基于Object.defineProperty()实现的。Object.defineProperty()只要是对某个属性进行拦截,所以有很多缺陷,比如:删除数据就无法监听,需要$delete等API 辅助才能监听到。
2.Option API 在组织代码较多组件时候不易维护。对于Option API 来说,所有的methods、computer都在一个对象里配置,这对小应用来说还好,但是代码超过300行的时候,新增或者修改一个功能,就需要不停的在data,methods里跳转写代码,上下反复横跳。
前面这些问题不是vue2 有意为之,大部分是发展的过程中碰见的。vue3 就是继承了vue2 具有响应式、虚拟DOM,组件化等所有优秀的特点,并且全部重新设计,解决了这些历史包袱的新框架,是一个拥抱未来的前端框架。下面我们就开始从七个方面来了解vue3 的新特性吧。
1.RFC机制
vue3 的第一个新特性和代码无关,而是vue 团队开发的工作方式,成立了Core Team,关于vue的新语法或者新功能的讨论,都会在GitHub上公开征求意见,宴请社区所有的人一起讨论,随时可以打开这个项目,vue3 正在讨论中的新需求,任何人都可以围观,参与讨论和尝试实现。这个改变让vue社区更加有活力,不管是
2.响应式系统
vue2的响应式机制是基于Object.defineProperty()这个API实现的,此外,vue 还使用了Proxy,这两者看起来都像是对数据的读写进行拦截,但是defineProperty试拦截具体某个属性,Proxy才是真正的代理。<br>
Object.defineProperty(obj, 'title', {
get() {},
set() {},
})
<br>
当项目里读取obj.title和修改obj.title的时候会被defineProperty拦截,但是defineProperty对不存在的属性无法拦截,所以vue2 中所有数据必须要在data里声明,而且,如果title是一个数组的时候,对数组的操作,并不会改变obj.title的指向,虽然我们可以通过拦截push等操作实现部分功能,但是对数组的长度和修改等操作还是无法实现拦截,所以还需要额外的$set等API.<BR/>
new Proxy(obj, {
get() { },
set() { },
})
这里需要注意的是,虽然Proxy拦截了obj这个数据,但是obj具体是什么属性,Proxy则不关心,统一拦截了,而且Proxy还可以监听更多数据类型,比如Set、Map,这是vue2 做不到的。当然,Proxy存在一些兼容性问题,这也是vue3 不兼容IE11以下浏览器的原因,还好现在IE用的人不多了。<br/>
更重要的是,我觉得Proxy 代表一种方向,就是框架会越来越多的拥抱浏览器的新特性。在Proxy普及之前,我们是没办法完整的监听一个JavaScript对象的变化,只能使用Object.defineProperty()去实现一部分功能。
3.自定义渲染器
vue2 内部所有的模块都是糅在一起的,这样做会导致不好扩展的问题,刚才我也提到一点,vue3 是怎么解决这个问题的呢?那就是拆包,使用最近流行的monorepo管理方式,响应式、编译和运行时全部独立了,
我们能看到,在vue3的组织架构中,响应式独立了出来,而vue2的响应式只服务与vue,vue3的响应式就和vue解耦了,我们甚至可以在Node.js和React中使用响应式。渲染逻辑也拆成了平台无关渲染逻辑和浏览器渲染API两部分。
在这个架构下,Node的一些库,甚至React都可以依赖响应式。在任何时候,如果你希望数据被修改了之后能通知你,都可以单独依赖vue3 的响应式。那么,在想要使用vue3 开发小程序、开发canvas小游戏,及开发客户端的时候,就不用赋值vue的代码了,只需要实现平台的渲染逻辑就可以了。
就像动画片《战胜金刚》,五个机器人可以独立执行任务,但关键时刻,高呼一声,“我来组成头部”,就可以合体,从而发挥整体的作用,vue3 也是一样,响应式。编译和运行时几部分组合在一起就是运行时在浏览器端的vue3,每个模块又都可以独立扩展出新的功能。
4.全部模块使用TypeScript重构
JavaScript是弱类型的语音,类型系统带来了更方便的提示,并且让我们的代码能够更健壮。现在大部分开源的框架都会引入类型系统,来对JavaScrupt进行限制,这样做的原因就是:1.类型系统带来了更方便的提示,2.类型系统让代码更健壮。<br/>
vue2那个时代基本只有两个技术选型,Facebook家的Flow.js和微软家的TypeScript,vue2 选择了Flow.js没问题,但是现在Flow.js被抛弃了,vue3选择了TypeScriot,TypeScript官方也对使用TypeScript开放vue3项目的团队更加友好。
5.Composition API 组合语法
Composition API 组合代码看起来有些繁琐,没有vue2 中Options API 的写法简单好懂,但Options API 的写法也有几个很严重的问题:<br/>
1.由于所有数据都挂载在this之上,因而Options API 的写法对TypeScript的类型推导很不友好,并且这样也不好做Tree'-shaking清理代码。<br/>
2.新增功能基本上都得修改data、method等配置,并且代码上300行之后,会经常上下反复横跳,不利于维护。<br/>
3.代码不好复用,vue2 的组件很难抽离通用逻辑,只能使用mixin,还会带来命名冲突的问题。<br/>
**使用Composition API 后,虽然看起来烦琐了些,但是也带了诸多好处:**
1.所有API都是import 引入的,用到的功能都import进来,对Tree-shaking很友好,打包会将很多不用的功能清理掉,减小包的大小。<br/>
2.不在上下反复横跳,我们可以把一个功能模块的methods、data都放在一起书写,维护更轻松。<br/>
3.代码方便复用,可以把一个功能所有的methods、data封装在一个独立的函数里,复用代码非常容易。<br/>
4.Composotion API 新增的return等语句,在实际项目中使用<script setup>特性可以清除,我们后续项目中都会用到这样的操作。
6.新的组件
1.Fragment:vue3 组件不在要求有一个唯一的根节点,清除了很多无用的占位div。<br/>
2.Teleport:允许组件渲染在别的元素内,主要开发弹窗组件的时候特别有用。<br/>
3.Suspense:异步组件,更方便开发有异步请求的组件。
7.新一代工程化Vite
1.Vite 不在vue3的代码包呢,和vue 也不是强绑定,Vite的竞品是Webpack。<br/>
2.Vite 主要是提示开发的体验,Webpack等工程化工具的原理,就是根据你的import依赖逻辑,形成一个依赖图,然后调用对应的处理工具,把整个项目打包后,放在内存里在启动。<br/>
3.由于要预打包,所以复杂项目的开发,启动调试环境需要3分钟都很常见,Vite 就是为了解决这个时间资源的消耗问题出现的。<br/>
4.现在浏览器都已经默认支持ES6的import 语法,Vite 就是基于这个原理来实现的,具体来说,在调试环境下,我们不需要全部预处理打包,只是吧首页依赖的文件依次通过网络请求去获取,整个开发体验得到巨大提升,做到了复杂项目秒级调试和热更新。<br/>
下图展示了Webpackde的工作原理,Webpack要把所有路由的依赖打包后,才能开始调试。<br>
而下图所示的是Vite的工作原理,一开始就可以准备联调,然后根据首页的依赖模块,再去按需加载,这样启动调试所需要的资源会大大减少。
总结
1.新的RFC机制也让我们所有人都可以参与vue新语法的讨论。<br/>
2.工程化工具Vite带来了更丝滑的调试体验。<br/>
3.对于产品的最终效果来看,vue3性能更高,体检更小。<br>
4.对于普通开发者来说,Composition API 组合语法带来了更好的组织代码的形式,全新的响应式系统基于Proxy,也可以独立使用。<br/>
5.vue3 内置了新的 Rragment、Teleport和Supense等组件。<br/>
6.对于vue 的二次开发来说,自定义渲染器让我们开发跨端应用更加得心应手。<br/>
7.对于vue的源码维护,全部模块使用TyoeScript重构,能够带来更好的可维护性。<br/>
简而言之,vue33带给我们的就是更快。更强且更易于扩展的开发体验,