vue3那些事
一、vue 版本历史2013年,在 Google 工作的尤雨溪,受到 Angular 的启发,开发出了一款轻量级框架,最初命名为 Seed2013年12月,更名为 Vue,版本号是 0.6.02014年1月24日,Vue 正式对外发布,版本号是 0.8.02014年2月25日,0.9.0 发布,有了自己的代号 Animatrix,这个名字来自动画版的《骇客帝国》,此后,重要的版本都会有自己的代号2
文章目录
一、vue 版本历史
- 2013年,在 Google 工作的尤雨溪,受到 Angular 的启发,开发出了一款轻量级框架,最初命名为 Seed
- 2013年12月,更名为 Vue,版本号是 0.6.0
- 2014年1月24日,Vue 正式对外发布,版本号是 0.8.0
- 2014年2月25日,0.9.0 发布,有了自己的代号 Animatrix,这个名字来自动画版的《骇客帝国》,此后,重要的版本都会有自己的代号
- 2015年6月13日,0.12.0发布,代号 Dragon Ball,Laravel 社区(一款流行的 PHP 框架的社区)首次使用 Vue,Vue 在 JS 社区也打响了知名度
- 2015年10月26日,1.0.0发布,代号 Evangelion,是 Vue 历史上的第一个里程碑。同年,vue-router(2015.8.18)、vuex(2015.11.28)、vue-cli(2015.12.27)相继发布,标志着 Vue从一个视图层库发展为一个渐进式框架
- 2016年10月1日,2.0.0发布,是第二个重要的里程碑,它吸收了 React 的虚拟 Dom 方案,还支持服务端渲染
- 2019年2月5日,2.6.0发布,代号 Macross,这是一个承前启后的版本,在它之后,推出了 3.0.0
- 2019年12月5日, Vue 3.0 源码公布
- 2020年09月18日,Vue 3.0 正式发布,代号 One Piece(海贼王),Vue3 支持 Vue2 的大多数特性,github上的tags地址:https://github.com/vuejs/vue-next/releases/tag/v3.0.0
二、为什么要推出 vue3
1、vue2的响应式弊端
随着 ES2015 标准的发布,其中一些新特性为 Vue 的性能提供了机会,例如Proxy
。而在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
这个特性就可以很好地解决上述的三个问题。
2、对 Typescript
的支持
- vue2 对于
Typescript
的支持不是很友好 - vue3中,源码就是使用
Typescript
编写的,所以天生就对Typescript
友好支持
3、vue3 比 vue2 有更小的 bundle 体积
三、vue3带来了什么
1、性能的提升
- 打包大小减少41%
- 初次渲染快55%, 更新渲染快133%
- 内存减少54%
…
2、源码的升级
- 使用
Proxy
代替defineProperty
实现响应式 - 重写虚拟 DOM 的实现和
Tree-Shaking
…
(Tree Shaking,摇树。意思就是按需引入,需要什么功能,就引入相对应的,可以减小最终bundle的体积。按需编译,体积更小。)
3、可以更好的支持Typescript
4、新的特性
(1) Composition AP
I(组合API)
setup
配置ref
与reactive
watch
与watchEffect
provide
与inject
…
(2) 新的内置组件
Fragment
- 文档碎片Teleport
- 瞬移组件的位置Suspense
- 异步加载组件的loading界面
(3) 其他改变
- 新的生命周期钩子
- data 选项应始终被声明为一个函数
- 移除 keyCode支持作为
v-on
的修饰符
…
四、创建 vue3.0 项目
1、使用 vue-cli 创建
官方文档:https://cli.vuejs.org/zh/guide/creating-a-project.html#vue-create
首先查看一下你的 @vue/cli 版本,确保 @vue/cli 版本在4.5.0以上
vue --version
# 或者 vue -V
如果没有安装或者版本不对,执行
# 安装或者升级你的@vue/cli
npm install -g @vue/cli
创建项目
vue create vue_demo
启动项目
cd vue_demo
npm run serve
2、使用 vite 创建
官方文档:https://v3.cn.vuejs.org/guide/installation.html#vite
vite官网:https://vitejs.cn
- 什么是vite?—— 下一代前端开发与构建工具。
- 现在的是 webpack,不晓得未来 vite 会发展如何,感兴趣的可以去官网学一下。
- vite 优势如下:
- 开发环境中,无需打包操作,可快速的冷启动。
- 轻量快速的热重载(HMR)。
- 真正的按需编译,不再等待整个应用编译完成。
- 传统构建 与 vite 构建对比图:
下图是 webpack,从 entry 入口文件进入,分析路由,进而分析模块,最终把这些东西进行一次打包,随后再告诉你 server ready 服务器准备好了。
下图是 vite,一开始就告诉你 server ready 服务器准备好了,如果你发起了一个 HTTP请求,它会从入口文件进去,根据你的 http 请求去找到对应路由,分析路由里的各个模块,最终告诉你东西弄好了,Dynamic import(code split point)动态导入(代码分割点)
创建项目
npm init vite-app vue_demo
进入项目目录,安装依赖
cd vue_demo
npm install
运行
npm run dev
目前 vite 还没有进行大规模的应用,开发时建议使用 vue-cli 创建。
五、分析项目初始结构
和 vue2 相比,有两处明显不同
第一处是 main.js 文件,vue3 中是如下
而 vue2 中是 import Vue,然后 new Vue 出来 vm。
第二处是 App.js文件,vue3 中是如下
而 vue2 中是需要在 template 中写个 div 之类的,把代码包进去。
六、vue3 的开发者工具
在 chrome 网上应用店搜索 vue,选择下面这种安装,特点是 logo 的右下角有个 beta
七、常用 Composition API(组合式 API)
官方文档:https://v3.cn.vuejs.org/guide/composition-api-introduction.html
1、setup
setup 是 Vue3 中一个新的配置项,值为一个函数。
在 vue2 中数据写在 data 里,方法写在 methods 里,而在vue3中,组件中所用到的数据、方法、计算属性、生命周期钩子等等,均要配置在setup中。
setup 函数有两种返回值:
若返回一个对象,则对象中的属性、方法, 在模板中均可以直接使用。如下所示:
若返回一个渲染函数,则可以自定义渲染内容,此时不管template里内容是什么,都会被覆盖掉,如下所示
注意点:
- 尽量不要与 Vue2 配置混用。 Vue2 配置(data、methods、computed…)中可以访问到 setup 中的属性、方法。但在 setup 中不能访问到 Vue2 配置。如果有重名,setup 优先。
- setup不能是一个 async 函数,因为返回值不再是 return 的对象, 而是promise, 模板看不到 return 对象中的属性。
2、ref 函数
在 vue2 中也有 ref,那是个标签属性,可以给某个元素做个标识,从而拿到这个元素的引用,类似于原生js中通过id操作dom元素。当然 vue2 中的这个 ref 在 vue3 中并没有被废除掉,而且在原来的基础上多了个 ref 函数。
-
ref 的作用是定义一个响应式的数据
-
语法:
let xxx = ref(initValue)
-
创建一个包含响应式数据的引用对象(reference对象,简称ref对象)。
-
JS中操作数据:
xxx.value
-
模板中读取数据: 不需要.value,直接:
<div>{{xxx}}</div>
-
接收的数据可以是基本类型,也可以是对象类型。
-
基本类型的数据响应式依然是靠
Object.defineProperty()
的get
与set
完成的。如下图所示为基本类型
-
对象类型的数据内部 “ 求助 ”了 Vue3 中的一个新函数
reactive
函数。如下图所示,为对象类型
3、reactive 函数
- 作用: 定义一个对象类型的响应式数据(基本类型不要用它,要用
ref
函数) - 语法:
const 代理对象= reactive(源对象)
接收一个对象(或数组),返回一个代理对象(Proxy的实例对象,简称proxy对象) - reactive定义的响应式数据是“深层次的”。
- 内部基于 ES6 的 Proxy 实现,通过代理对象操作源对象内部数据进行操作。
- 如下所示:
4、reactive 和 ref 对比
- 从定义数据角度对比:
- ref用来定义:基本类型数据。
- reactive用来定义:对象(或数组)类型数据。
- ref也可以用来定义对象(或数组)类型数据, 它内部会自动通过
reactive
转为代理对象。
- 从原理角度对比:
- ref通过
Object.defineProperty()
的get
与set
来实现响应式(数据劫持)。 - reactive通过使用
Proxy
来实现响应式(数据劫持), 并通过Reflect
操作源对象内部的数据。
- ref通过
- 从使用角度对比:
- ref定义的数据,操作数据需要
.value
,读取数据时模板中直接读取不需要.value
。 - reactive定义的数据,操作数据与读取数据均不需要
.value
。
- ref定义的数据,操作数据需要
八、vue2 和 vue3 中的响应式原理
1、vue2 的响应式原理
- 实现原理:
-
对象类型:通过
Object.defineProperty()
对对象的属性的读取、修改进行拦截(数据劫持)。 -
数组类型:通过重写更新数组的一系列方法来实现拦截。(对数组的变更方法进行了包裹)。
-
Object.defineProperty(data, 'count', {
get () {},
set () {}
})
- 存在问题:
- 无法将 data 新增的属性转为响应式,只能通过 vue 提供的
Vue.set
或者this.$set
向data中对象新增响应式属性。 - 不能通过下标或者 length 属性响应式地改变数组,而是必须得用数组的方法
push、pop、shift、unshift、splice
来响应式地改变数组。
- 无法将 data 新增的属性转为响应式,只能通过 vue 提供的
2、vue3 的响应式原理
- 实现原理:
const p = new Proxy(data, {
//有人读取p的某个属性时调用
get (target, prop) {
return Reflect.get(target, prop)
},
//有人修改p的某个属性、或给p追加某个属性时调用
set (target, prop, value) {
return Reflect.set(target, prop, value)
},
//有人删除p的某个属性时调用
deleteProperty (target, prop) {
return Reflect.deleteProperty(target, prop)
}
})
proxy.name = 'tom'
九、未完待续…
更多推荐
所有评论(0)