前言
vue2.x向vue3.x过渡,都改变了什么呢?本文从创建vue3项目起步,一起来看看vue3有什么样的改变,以及可以带给我们什么好处吧~
一 、为什么学Vue3
1. 现状
- 2020.09.18发布,周边生态不支持,大多数开发者处于观望。
- 主流组件库
element-plus
、vant
、ant-design-vue
等已经发布支持Vue3.0的版本,这是趋势。
2. Vue3优点
- 国内最火前端框架之一
- 性能提升
- 体积更小
- 类型推断:更好的支持TS(js的超集)
- 高级给予,暴露了更底层的API和提供更先进的内置组件
☆
选项API----->组合API(composition api),能够更好的组织逻辑,封装逻辑,复用逻辑(编程风格改变)
3. Vue3展望
- 趋势
- 大型项目,由于对Ts的友好,越来越多的大型项目可以使用vue3.0
二、 如何创建vue3应用
1. 基于Vue脚手架创建项目
# 全局安装vue脚手架
npm i @vue/cli -g
# 创建Vue项目,选择v3版本
vue create 项目名称
#--------创建完成后--------
# 切换路径
cd 项目名称
# 运行项目
npm run serve
操作步骤:
-
找到要创建项目的根目录,地址栏输入
cmd
打开终端 -
输入
vue create 项目名称
,项目名称自己起哦~ -
选择手动创建(如图)
- 选择需要的配置(空格选择,选择完毕后回车即可)
- 各项配置按照下图选择即可
2. 入口文件分析
vue3的API典型风格:按需导入
链式操作
作用:把App根组件渲染到index.html
页面中
总结:
- Vue的实例化方式发生变化:基于createApp方法进行实例化
- router和store采用use方法进行配置
- 按需导入,为了提升打包的性能
3. App.vue根组件结构分析
Vue2中的组件模板必须有唯一的根节点
Vue3中组件的模板可以没有根节点
总结:Vue3中组件的模板可以没有根节点(与Vue2进行对比)
4. router文件分析
Vue3创建实例对象
结论:
- 创建路由实例对象,采用createRouter方式,Vue3典型风格
- 采用hash和history的方式有变化
- Vue2采用mode选项:hash / history
- Vue3采用方法:createWebHashHistory()/createWebHistory()
5. vuex文件分析
结论:创建store对象采用createStore方法,而不是new
三、 选项API 和 组合API
目标:理解什么是选项API写法,什么是组合API
1. 选项API
每个代码写到哪个位置
2. 组合API
按照功能划分
总结:
- Vue2项目中使用的选项API
- 代码风格:一个功能逻辑代码分散
- 优点:易于学习 和使用,写代码的位置已经约定好
- 缺点:代码组织性差,相似的逻辑(功能)代码不便于复用,逻辑复杂
- 组合API(hook)
- 以功能为单位阻止代码结构,后续重用功能更加方便
四、 组合API相关方法
1. setup函数
使用细节:
-
新的组件选项,作为组件中使用组合API的起点
-
从组件生命周期来看,它的执行顺序在
beforeCreate
之前(Vue3中beforeCreate/created已经被废弃了,其实已经被setup替代了) -
setup函数中this还没有创建,此时无法访问this,this是undefined
-
setup中返回的数据用于模板使用:类似于之前的data中提供的数据
-
Vue3中依然可以使用data中的数据,但是不建议使用(这是选项API的写法)
-
方法在setup中定义后,也需要return出去
语法格式:
export default {
setup() {
// return ...
}
}
结论:
- setup选项是实现组合API的基础
- 触发的时机:
- this问题
- setup的返回值
2. 生命周期
vue2.x生命周期钩子函数:
- beforeCreate
- created
- beforeMount
- mounted
- beforeUpdate
- updated
- beforeDestory
- destroyed
认识vue3.0生命周期钩子函数(相同的生命周期函数可以触发多次)
setup
创建实例前onMounted
挂载DOM后onBeforeUpdate
更新组件前onUpdated
更新组件后onBeforeUnmount
卸载销毁前onUnmounted
:卸载销毁后
语法格式:
import {
mounted } from 'vue'
export default {
setup () {
mounted(() => {
console.log('xxx')
})
}
}
结论:
- vue3生命周期函数发生了变化
- 去掉两个:
beforeCreate
和created
,添加了setup- 方法名发生变化: 方法名前面多了个on ,中间是驼峰
- 卸载组件的生命周期变化:
onBeforeUnmount
、onUnmounted
- 特点:同一个生命周期可以触发多次
五、数据响应式
数据的响应式:数据的变化导致视图自动变化。
1. reactive函数
可以定义一个复杂数据类型
语法格式:
模板中使用obj.msg
import {
reactive } from 'vue'
export default{
setup(){
const obj = reactive({
msg: 'Hello'
})
}
}
注
:reactive中的对象属性如果重新赋值会失去响应式能力
2. toRef函数
需求:模板中不添加obj前缀,直接获取属性
把对象中的单个属性取出来,保证数据的响应式
语法格式:
import {
toRef } from 'vue'
export default {
const obj = {
msg: 'hello'
}
const msg = toRef(obj,'msg')
setup() {
return {
msg}
}
}
代码演示:
<template>
<div>
<div>{
{
msg }}</div>
<div>{
{
info }}</div>
<button @click="handleClick">点击</button>
</div>
</template>
<script>
import {
reactive, toRef } from 'vue'
export default {
name: 'App',
setup() {
const obj = reactive({
msg: 'hello',
info: 'Leo'
})
const msg = toRef(obj, 'msg')
const info = toRef(obj, 'info')
const handleClick = () => {
obj.msg = 'hi'
}
return {
msg, info, handleClick }
}
}
</script>
<style lang="less"></style>
结论: toRef方法可以把对象中的单个属性取出,并且保证响应式能力
3. toRefs函数
语法格式:
import {
toRefs } from 'vue'
export default {
setup() {
const obj = reactive({
msg: 'hello',
info: 'Leo'
})
// 把obj中的属性解构出来
const {
msg,info} = toRefs(obj)
return {
msg, info}
}
}
结论:toRefs这个方法可以批量转换对象中的属性为独立的响应式数据
4. ref函数
主要用于定义普通(基本类型)的数据并保证响应式能力
语法格式:
import {
ref} from 'vue'
export default {
setup () {
const count = ref(