Vue3的新特性
-
向下兼容,vue3支持大多数vue2的特性 -
Composition API
- setup、ref、reactive、watch、watchEffect、生命周期钩子等等
-
新的内置组件
- Fragment、Teleport、Suspense(实验)
-
Tree-shaking优化,性能提升 -
更好的支持TypeScript
一、向下兼容
vue3支持大多数vue2的特性(可以写vue2的东西 )
- vue2 添加Object数据 需 this.$set 或 Vue.set, 删除 需要Vue.delete 或者可能得使用其他的一些办法来解决这个问题
- Vue3 添加object数据 删除都是响应式
二、Composition API
1.setup
- setup函数是一个新的组件选项,作为在Composition API的入口点
- 接收两个参数props和context(attrs、slots、emit)
- props:值为对象,内容:组件外部传递过来,且组件内部声明接受了的属性
- context: 上下文对象
- attrs:值为对象,包含:组件外部传递过来但没有在props配置中声明的属性,相当于vue2中的this.$attrs
- slots: 收到的插槽内容,相当于this.$slots
- emit: 分发自定义的事件的函数,相当于this.$emit
- 执行时机:setup处于 beforeCreate生命周期钩子之前的函数(this为undefined)
- 返回值:(两种返回值)
- 返回一个对象,对象中的属性、方法,在模板中均可以直接使用
- 返回一个渲染函数:自定义渲染内容(代替模板)
2.Ref和Reactive
ref 和 reactice 都是用来创建响应式对象的
- ref
- 使用的时候需要.value
- 声明基本数据类型时使用Object.definePropety 的 原型对象中的get set方法来修改数据实现响应式
- 声明Object类型时内部通过reactive来转为代理对象
- template模板中不需要.value
- reactice
- 用来定义Object类型数据
- 操作数据与读取数据都不需要.value
- 通过使用Proxy来实现响应式,并通过Reflect操作元对象内部的数据
3、生命周期钩子
setup执行时机在beforeCreate之前执行;
将beforeDestroy 改名为beforeUnmount ,destroyed 改名为unmounted
- setup() :开始创建组件之前,在beforeCreate之前执行。创建的是data和method
- onBeforeMount() : 组件挂载到节点上之前执行的函数。
- onMounted() : 组件挂载完成后执行的函数。
- onBeforeUpdate(): 组件更新之前执行的函数。
- onUpdated(): 组件更新完成之后执行的函数。
- onBeforeUnmount(): 组件卸载之前执行的函数。
- onUnmounted(): 组件卸载完成后执行的函数
- onActivated():若组件实例是
<KeepAlive> 缓存树的一部分,当组件被插入到 DOM 中时调用。 - onDeactivated(): 若组件实例是
<KeepAlive> 缓存树的一部分,比如从 A 组件,切换到 B 组件,A 组件消失时执行。 - onErrorCaptured(): 在捕获了后代组件传递的错误时调用。(以下为错误来源)
- 组件渲染
- 事件处理器
- 生命周期钩子
setup() 函数- 侦听器
- 自定义指令钩子
- 过渡钩子
4、计算属性
与vue2中的computed配置功能一致,vue2 计算属性是一个对象 vue3是函数
const count = ref(1)
const plus = computed(() => count.value ++)
const state = reactive({
title: computed(() => {
return count.value + 1
}),
})
5、watch
watch 可以接收三个参数 第一个是要监听的对象,第二个是数据处理变化,第三个是配置项(options)
options: immediate:true是刚一进去就监听一次
- 监听ref定义的响应式数据(监听多个可以写成数组形式)
const num = ref(0)
const msg = ref('watch')
watch(
num,
(newV, oldV) => {
console.log(newV)
},
{ immediate:true }
)
使用reactive定义的数据,无法正确获取oldV;并且强制开启了深度检测(deep配置无效)
const state = reactive({
age: 18,
name: 'fc',
tag: {
a: 3,
}
})
watch(
state,
(newV, oldV) => {
console.log(newV)
},
{ deep: true }
)
watch(
state.tag,
(newV, oldV) => {
console.log(newV)
},
{ deep: true }
)
6、watchEffect
watch:既要指明监视的属性,也要指明监视的回调
watchEffect:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性
- watchEffect所指定的回调中用到的数据只要发生变化,则直接重新执行回调
- watchEffect与computed比较相似
- computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值
- watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值
7、模板指令
-
v-model 用法更改,在一个组件上支持双向绑定多个属性,例如v-model:first-name="first" v-model:last-name="last" ,还有子组件defineProps(['']) defineEmits(['']) 来接收和响应事件来更新数据 -
移除keyCode v-on的修饰符,同时也不再支持config.keyCodes (废除 @keyup.13这种还有 自定义按键别名的) -
移除v-on.native 修饰符 vue3之中使用emit 接收自定义事件 接受的vue认为是自定义的 不接受的vue会认为是原生事件 -
移除过滤器 vue3认为这个有实现成本,官方目前建议用方法调用或计算属性 -
v-if 与 v-for 的优先级对比
- 2.x 版本中在一个元素上同时使用 v-if 和 v-for 时,v-for 会优先作用。Vue2.x v-for 优先级高
- 3.x 版本中 v-if 总是优先于 v-for 生效。Vue3.x v-if 优先级高
-
v-bind 合并行为
- 在 2.x,如果一个元素同时定义了 v-bind=“object” 和一个相同的单独的 property,那么这个单独的 property 总是会覆盖 object 中的绑定。 单独的属性覆盖v-bind
- 在 3.x,如果一个元素同时定义了 v-bind=“object” 和一个相同的单独的 property,那么声明绑定的顺序决定了它们如何合并
-
v-for 中的 Ref 数组
- 在 Vue 2 中,在 v-for 里使用的 ref attribute 会用 ref 数组填充相应的 $refs property。当存在嵌套的 v-for 时,这样会效率低下
- 在 Vue 3 中,这样的用法将不再在 $ref 中自动创建数组。要从单个绑定获取多个 ref,而是将 ref 绑定到一个更灵活的函数上 (新特性)
<div v-for="item in list" :key="item" :ref="setItemRef"></div>
export default {
setup() {
let itemRefs = []
const setItemRef = el => {
if (el) {
itemRefs.push(el)
}
}
return {
setItemRef
}
},
}
8、provide inject props emit
9、setup语法糖
-
<script setup> -
更少的模板语法 -
组件只需引入不用注册,属性和方法也不用返回,setup函数也不需要,export default不用写,数据,计算属性和方法,自定义指令都是在template中直接可获取 -
不写setup函数,props/emit的获取方法
defineProps : 用来接收父组件传来的值propsdefineEmits : 用来声明触发的事件表 -
可以直接写await 组件的setup会自动百年城 async setup
10、getCurrentInstance
getCurrentInstance() : 用于获取当前组件的实例、上下文来操作router和vuex等
11、hooks
vueuse
12、toRef toRefs
- 创建一个ref对象,其value值指向另一个对象中的某个属性值(引用)
- toRefs与toRef功能一致,但可以批量创建多个ref对象
13、shallowReactive shallowRef
- shallowReactive: 中会处理对象最外层(第一层)属性的响应式(浅响应式)
- shallowRef:只处理基本数据类型的响应式,不进行对象的响应式处理(针对基本类型,用法与ref一样,针对对象类型,不会对里面属性进行响应式处理,只会针对对象本身,如果替换对象可以响应式)
14、readonly shallowReadonly
- readonly: 让一个响应式数据变为只读的(深只读)
- shallowReadonly:让一个响应式数据变为只读的(浅层只读 深层还是响应式)
15、toRaw markRaw
toRaw : 将一个由reactive生成的响应式对象转为普通对象markRaw : 标记一个对象,使其永远不会再成为响应式对象
三、新的内置组件
1、Teleport
一种能够将模板移动到其他位置的组件
应用: modal、toast
<teleport to="#modal"></Teleport>
2、Suspense(试验)
等待异步组件时渲染一些额外内容,让应用有更好的用户体验
3、Fragment
在 Vue2 中, template中只允许有一个根节点;在 Vue3 中,可以直接写多个根节点
四、Tree-shaking
Tree-Shaking带来的bundle体积更小。
在Vue2版本中,很多函数都挂载在全局Vue对象上,比如nextTick、nextTick、nextTick、set等函数,因此虽然我们可能用不到,但打包时只要引入了vue这些全局函数仍然会打包进bundle中。
而在Vue3中,所有的API都通过ES6模块化的方式引入,这样就能让webpack或rollup等打包工具在打包时对没有用到API进行剔除,最小化bundle体积
|