TS 与 Vue3
TS 与 defineProps
之前的用法
defineProps
配合 vue
默认语法进行类型校验。
defineProps({
money: {
type: Number,
required: true
},
car: {
type: String,
required: true
}
})
可以看到代码繁琐,如果变量多,则代码量会剧增。
配合 ts
使用
defineProps
配合 ts
的泛型定义 props
类型校验,好处是更直接,代码量更轻松。
defineProps<{
money: number
car?: string
}>()
默认值设置
通过解构方法设置默认值,但是 ts 没有解构的方法,需要额外进行设置。去到 vite.config.ts
文件下,设置如下代码:
export default defineConfig({
plugins: [vue(
{
reactivityTransform: true
}
)]
})
现在可以使用解构的语法了。通过等号赋值设置默认值即可。
const {name, age=20, love} = defineProps<{
name: string
age?: number
love: { first: string, second: string, third: string, forth: string}
}>()
TS 与 defineEmits
之前的写法
const emit = defineEmits(['change', 'update'])
配合 ts
使用
配合 ts 使用,可以实现更细粒度的校验。
const emit = defineEmits<{
(event: 'getFn', id: number): void
}>()
const btn = () => {
emit('getFn', 100)
}
此时调用 emit
需要传入函数名和参数。
TS 与 ref
简单数据类型
通过泛型指定value的值类型,如果是简单值,该类型可以省略
const money = ref<number>(10)
const money = ref(10)
复杂数据类型
复杂数据类型推荐使用泛型来指定
type Todo = {
id: number
name: string
done: boolean
}
const list = ref<Todo[]>([])
setTimeout(() => {
list.value = [
{ id: 1, name: '吃饭', done: false },
{ id: 2, name: '睡觉', done: true }
]
})
TS 与 computed
泛型可以指定 computed
计算属性的类型,通常可以省略。
const leftCount = computed<number>(() => {
return list.value.filter((item) => item.done).length
})
console.log(leftCount.value)
TS 与 事件处理
const move = (e: MouseEvent) => {
mouse.value.x = e.pageX
mouse.value.y = e.pageY
}
<h1 @mousemove="move($event)">根组件</h1>
TS 与 Template Ref
const imgRef = () => {
if(ref.value) {
ref<HTMLImageElement>(null)
}
}
onMounted(() => {
console.log(imgRef.value?.src)
})
可选链操作符
可选链操作符( ?.
)允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效
let nestedProp = obj.first?.second;
console.log(res.data?.data)
obj.fn?.()
if (obj.fn) {
obj.fn()
}
obj.fn && obj.fn()
// 等价于
let temp = obj.first;
let nestedProp = ((temp === null || temp === undefined) ? undefined : temp.second);
非空断言
如果我们明确的知道对象的属性一定不会为空,那么可以使用非空断言 !
。
// 告诉typescript, 明确的指定obj不可能为空
let nestedProp = obj!.second;
注意:
非空断言一定要确保有该属性才能使用,不然使用非空断言会导致
bug
。