Vue 3.3亮点解析:不容错过的新特性及其影响
这张图看起来不错
概览
Vue 3.3的最新版本主要目标是优化开发者的使用体验,包括引入一些新的简化语法和宏,以及在TypeScript方面的进一步提升。
以下是主要的更新内容:
- 为setup语法糖组件引入了
泛型功能
; - 允许在组件文件中
导入外部的ts类型
; - 对
defineEmits
语法进行了优化; - 新增-
defineSlots
定义插槽类型; - 新增-
defineModel
来简化modelValue的语法; - 新增-
defineOptions
定义组件名称以及其他一些配置项; - 对
toRef和toValue
的功能进行了增强。
接下来对这些改动一一介绍
更新
setup语法糖泛型
使用<script setup>
的组件现在可以通过generic
属性接受泛型类型参数,一般情况下用不到,但有时候组件笔记复杂时无法推断类型的时候非常有用
<script setup lang="ts" generic="T">
defineProps<{
items: T[]
selected: T
}>()
</script>
注意:eslint可能会报错,需要关闭该选项的检查
支持导入外部ts类型
defineProps
和defineEmits
支持使用import外部导入的类型声明。
<script setup lang="ts">
import type { Props } from './foo'
// 使用导入的类型 + 交集类型(导入类型基础上增加一个字段)
defineProps<Props & { extraProp?: string }>() //在vue3.3之前不支持使用import导入的类型
</script>
defineEmits语法优化
之前defineEmits
的类型参数只支持调用签名语法:
const emit = defineEmits<{
(e: 'foo', id: number): void
(e: 'bar', name: string, ...rest: any[]): void
}>()
// 或者不定义类型
// const emit = defineEmits(['update:modelValue'])
在vue3.3中可以简化为以下写法,更加简洁(当然原来的写法照样可以继续使用)
const emit = defineEmits<{
foo: [id: number]
bar: [name: string, ...rest: any[]]
}>()
新增defineSlots
新的defineSlots
宏可以用来声明插槽的类型,例如:
子组件Pant
<script setup lang="ts">
defineSlots<{
default?: (props: { msg: string }) => any
item?: (props: { id: number }) => any
}>()
</script>
父组件
<template>
<Pant :list="list">
<template #default="{ msg }">{{ msg }}</template>
<Pant/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { listType } from '@/types/api'
const list = ref<Array<listType>>([])
</script>
新增defineModel
在vue3.3中此功能是实验性的,需要明确的选择加入
用于简化自定义v-model双向绑定语法,在原来需要声明props,并定义update:propName事件
<template>
<input :value="modelValue" @input="onInput" />
</template>
<script setup>
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
function onInput(e) {
emit('update:modelValue', e.target.value)
}
</script>
简化后的写法
<template>
<input v-model="modelValue" />
</template>
<script setup>
const modelValue = defineModel()
// 也可以直接修改,等价于emit('update:modelValue', '新值')
// modelValue.value = '新的值'
</script>
新增 defineOptions
新的defineOptions
宏允许直接在<script setup>
中声明组件选项,而不需要单独的<script>
块
可以用 defineOptions
定义任意选项,但 props
, emits
, expose
, slots
除外
<script setup>
defineOptions({
name: 'Pant'
inheritAttrs: false
})
</script>
toRef和toValue增强
toRef
已得到增强,以支持将值/getter/现有refs规范化为refs:
js
// 等价于ref(1)
toRef(1)
// 创建一个readonly ref,在.value访问时调用getter
toRef(() => props.foo)
// 按原样返回现有的引用
toRef(existingRef)
使用getter调用toRef
类似于computed
,但当getter只是执行属性访问而没有昂贵的计算时,效率会更高。
新的toValue
实用程序方法提供了相反的功能,将values / getters / refs标准化为值:
js
toValue(1) // --> 1
toValue(ref(1)) // --> 1
toValue(() => 1) // --> 1
toValue
可以在composable中代替unref
使用,这样你的composable就可以接受getter作为反应式数据源:
js
// 以前:分配不必要的中间引用
useFeature(computed(() => props.foo))
useFeature(toRef(props, 'foo'))
// 现在:更高效和简洁
useFeature(() => props.foo)
toRef
和toValue
之间的关系类似于ref
和unref
之间的关系,主要区别在于对getter函数的特殊处理。
关于依赖
升级到3.3时,vue作者建议同时更新以下依赖项:
- volar / vue-tsc@^1.6.4
- vite@^4.3.5
- @vitejs/plugin-vue@^4.2.0
- vue-loader@^17.1.0(如果使用webpack或vue-cli)
JSX导入源
从3.3版本开始,Vue允许用户通过TypeScript的jsxImportSource选项来指定JSX命名空间,让用户可以根据需要选择全局或按文件进行选择。
尽管如此,为了保持向后兼容性,3.3版本仍然会全局注册JSX命名空间。作者计划在3.4版本中取消默认的全局注册。如果你现在正在使用TSX和Vue,建议升级到3.3版本后,应显式地在tsconfig.json
文件中添加jsxImportSource
选项,以避免在3.4版本发布时出现问题。
总结
哈哈哈,总结已经在 概览 里面了,本文只记录了一部分比较重点的更新,完整更新日志可以去看vue.js的github日志
转载自:https://juejin.cn/post/7233053557833056317