使用 TypeScript 为 Vue3.2 + 标注类型方式
为 ref 标注类型
// 第一种:
import { ref } from "vue"
const num = ref<string | number>("888")
// 第二种:
import { ref } from "vue"
interface User {
name: string
age: string | number
}
const user = ref<User>({
name: "昊轩",
age: 25,
})
// 第三种: (复杂)
import { ref } from "vue"
import type { Ref } from "vue"
const num: Ref<string | number> = ref("666")
为 reactive 标注类型
// 第一种:自动推导
import { reactive } from "vue"
// 推导得到的类型:{ title: string }
const name = reactive({ name: "昊轩" })
// 第二种:
import { reactive } from "vue"
interface User {
name: string
age: string | number
}
const user: User = reactive({
name: "昊轩",
age: "25",
})
为 computed 标注类型
// 第一种:从计算函数的返回值上自动推导
import { ref, computed } from "vue"
const count = ref<num>(666)
const user = computed(() => "昊轩" + count.value)
// 第二种:通过泛型参数显式指定类型 (推荐)
const user = computed<string>(() => {
return "昊轩"
})
为 props 标注类型
// 第一种:通过泛型参数来定义 props 的类型 (基于类型的声明)
const props = defineProps<{
name: string
age?: number
}>()
// 第二种: (基于类型的声明)
interface Props {
name: string
age?: number
}
const props = defineProps<Props>()
// 第三种 Props 解构默认值 当使用基于类型的声明时,我们失去了为 props 声明默认值的能力。这可以通过 withDefaults 编译器宏解决:
export interface Props {
msg?: string
labels?: string[]
}
const props = withDefaults(defineProps<Props>(), {
msg: "hello",
labels: () => ["one", "two"],
})
为 emits 标注类型
// 运行时
const emit = defineEmits(["change", "update"])
// 基于类型
const emit = defineEmits<{
(e: "change", id: number): void
(e: "update", value: string): void
}>()
// 3.3+: 可选的、更简洁的语法
const emit = defineEmits<{
change: [id: number]
update: [value: string]
}>()
// 若没有使用 <script setup>,defineComponent() 也可以根据 emits 选项推导暴露在 setup 上下文中的 emit 函数的类型:
import { defineComponent } from "vue"
export default defineComponent({
emits: ["change"],
setup(props, { emit }) {
emit("change") // <-- 类型检查 / 自动补全
},
})
为事件处理函数标注类型
// 在处理原生 DOM 事件时,应该为我们传递给事件处理函数的参数正确地标注类型。让我们看一下这个例子:
<template>
<input type="text" @change="handleChange" />
</template>
<script setup lang="ts">
function handleChange(event) {
// `event` 隐式地标注为 `any` 类型
console.log(event.target.value)
}
// 没有类型标注时,这个 event 参数会隐式地标注为 any 类型。这也会在 tsconfig.json 中配置了 "strict": true 或 "noImplicitAny": true 时报出一个 TS 错误。因此,建议显式地为事件处理函数的参数标注类型。此外,你在访问 event 上的属性时可能需要使用类型断言:
function handleChange(event: Event) {
console.log((event.target as HTMLInputElement).value)
}
</script>
为模板引用标注类型
模板引用需要通过一个显式指定的泛型参数和一个初始值 null 来创建:
<template>
<input ref="el" />
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
const el = ref<HTMLInputElement | null>(null)
onMounted(() => {
el.value?.focus()
})
</script>