vue3.x 开始
2020年 9.18发布3.0版本、代号: One Piece (海贼王),耗时两年,2600+提交,99位贡献者。
vue2.x 面临的问题
vue2.x版本发布于数年前,基于es5的技术架构,受限于当时通用浏览器的版本问题,在某些功能方面做了一些妥协:
- 监听数据的方法
Object.definePerproty
, 不能对Object类型做深度监听。而为了深度监听,以及为了达到目的所要付出的代价,也就是递归遍历侦听数据 optionsApi
存在问题,功能分块混乱,我们需要把逻辑分别散落在data,methods、computed
对象里,新增一个需求就需要分别在各项里修改,来回滚动- vue2.0缺少一种较为简洁的低成本的机制来完成逻辑复用,虽然可以minxis完成逻辑复用,但是当mixin变多的时候,会使得难以找到对应的data、computed或者method来源于哪个mixin,使得类型推断难以进行
- ts支持不友好
2.0 / 3.0 实现原理
- Vue2.0: 实现MVVM(双向数据绑定)的原理是通过
Object.defineProperty
来劫持各个属性的setter、getter
在数据变动时发布消息给订阅者,触发相应的监听回调。
缺点:
基于Object.defineProperty
不具备监听数组的能力,需要重写数组的原型方法来达到响应式。Object.defineProperty
无法检测到对象属性的添加和删除 。
由于Vue会在初始化实例时对属性执行getter/setter转化,所有属性必须在data对象上存在才能让Vue将它转换为响应式。
深度监听需要一次性递归,对性能影响比较大 - Vue3.0: 重构响应式系统,使用
Proxy
代理 +Reflect
反射,替换Object.defineProperty
使用Proxy代理优势:
可直接监听数组类型的数据变化
监听的目标为对象本身,不需要像Object.defineProperty一样递归遍历每个属性,有一定的性能提升
可拦截apply、ownKeys、has等13种方法,而Object.defineProperty不行
不需要一次性遍历data的属性,可以显著提高性能。
因为Proxy是ES6新增的属性,有些浏览器还不支持,只能兼容到IE11
源码:
const proxyData = new Proxy(data, {
get(target,key,receive){
// 只处理本身(非原型)的属性
const ownKeys = Reflect.ownKeys(target)
if(ownKeys.includes(key)){
console.log('get',key) // 监听
}
const result = Reflect.get(target,key,receive)
return result
},
set(target, key, val, reveive){
// 重复的数据,不处理
const oldVal = target[key]
if(val == oldVal){
return true
}
const result = Reflect.set(target, key, val,reveive)
return result
},
// 删除属性
deleteProperty(target, key){
const result = Reflect.deleteProperty(target,key)
return result
}
})
vue3带来了什么?
打包大小减少41%、初次渲染快55%、更新渲染快133%、内存减少54%
- 新增
Composition API
更好的逻辑复用和代码组织
Vue2.0中,随着功能的增加,组件变得越来越复杂,越来越难维护,而难以维护的根本原因是Vue的API设计迫使开发者使用watch,computed,methods选项组织代码,而不是实际的业务逻辑。Composition Api
的出现,主要是也是为了解决Option API带来的问题
第一个是代码组织问题,Compostion API可以让开发者根据业务逻辑组织自己的代码,让代码具备更好的可读性和可扩展性,也就是说当下一个开发者接触这一段不是他自己写的代码时,他可以更好的利用代码的组织反推出实际的业务逻辑,或者根据业务逻辑更好的理解代码。
第二个是实现代码的逻辑提取与复用,当然mixin也可以实现逻辑提取与复用,但是像前面所说的,多个mixin作用在同一个组件时,很难看出property是来源于哪个mixin,来源不清楚,另外,多个mixin的property存在变量命名冲突的风险。而Composition API刚好解决了这两个问题。 - 重构
Virtual DOM
Vue2 中的虚拟dom 是进行全量对比
Vue3 新增静态标记,模板编译时的优化,将一些静态节点编译成常量
slot优化,将slot编译为lazy函数,将slot的渲染的决定权交给子组件
模板中内联事件的提取并重用(原本每次渲染都重新生成内联函数)
Vue3.x搭建起步
安装好vue-cli后, 终端输入vue -V 出现4.5.x以上版本为3.x的脚手架。
使用脚手架创建第一个3.x项目:
Vue create vue3demo01
使用 Vite
创建项目:
全局安装vite:
npm install -g create-vite-app
创建项目
create-vite-app yourProjectName
- npm:
npm init @vitejs/app 按照提示操作
or
npm init @vitejs/app my-vue-app
- yarn:
yarn create @vitejs/app 按照提示操作
or
yarn create @vitejs/app my-vue-app
- 你还可以通过附加的命令行选项直接指定项目名称和你想要使用的模板
例如,要构建一个 Vite + Vue 项目运行:
yarn create @vitejs/app my-vue-app --template vue
例如创建 vue+ts:
yarn create @vitejs/app my-vue-app --template vue-ts