TypeScript基础结合Vue3应用
defineProps与Typescript
运行时声明:原本的JS写法也支持类型校验 src/components/ChildCom.vue
defineProps({
money: Number,
car: {
type: String,
default: 'benchi'
}
})
基于类型的声明(推荐使用)
❗注意事项:
- 小括号() 不传任何函数实参
- 尖括号<> 传递泛型类型参数
编译器会尽可能地尝试根据类型参数推导出等价的运行时选项。
defineProps 宏函数,非标准的 JS 函数,主要是给脚手架编译用的,使用的时候不需要导入
defineProps<{
money: number
car?: string
}>()
使用 src/App.vue
<ChildCom :moeny="200" />
props默认值和开启响应性
解决没有默认值的情况
src/components/ChildCom.vue
const { moeny=100 } = defineProps<{ moeny:number }>
<h3>moeny: {{ moeny }}</h3>
vite.config.ts
plugins:[
Vue({
reactivityTransform:true
})
]
defineEmits与Typescript
src/components/ChildCom.vue
运行时声明(能用,但不严谨)
const emit = defineEmits(['getValFromSon','changeMoney'])
基于类型声明(推荐使用)
const emit = defineEmits<{
(e:'getValFromSon',val:number):void,
(e:'changeMoney'):void
}>()
触发自定义事件并传递参数
const btn = () => {
emit('getValFromSon',100)
}
父子组件通讯与TS
绑定自定义事件获取子组件传递的数据 src/App.vue
<ChildCom :moeny="200" @getValFromSon="getValFromSon" />
const getValFromSon = (val:number) = {
console.log('父组件接收到数据', val)
}
ref 与 TS
ref 基本类型,可以省略泛型的类型注解
const num = ref(1400)
ref 复杂类型,建议通过泛型指定
const list = ref<number[]>([])
应用
// Todo 对象结构
interface Todo{
id:number
content:string
done:boolean
}
// Todo[] 数组的每一项都是 Todo 对象结构
const todoList = ref<Todo[]>()
todoList.value = [
{
id: 1,
content: '吃饭',
done: true,
},
]
reactive 与 TS
经验:
大部分情况下不需要书写类型声明,reactive 能自动根据初始值自动推导
import { reactive } from 'vue'
// 不使用类型声明
const obj1 = reactive({ title: 'Hello' })
// 使用类型声明
interface ObjType = {
title:string
}
const obj2:ObjType = reactive({ title: 'Hello' })
computed与TS
经验:
大部分情况下是不需要写类型注解,computed 会根据返回值自动推导类型
const num = ref(100)
// 使用类型声明
const doubleNum = computed<number>(()=>{ return num.value*2 })
事件处理函数与TS
Event
通用事件对象
- 通用事件对象 Event 能访问通用属性
.target
MouseEvent
鼠标事件对象(鼠标坐标属性)
- 鼠标事件对象 MouseEvent 能访问鼠标坐标
.clentX .clientY
const handleClick = ( e:MouseEvent ) => {
console.log(e.clientX)
}
// @click="handleClick"
KeyboardEvent
键盘事件对象(键盘按键属性)
- 键盘事件对象 KeyboardEvent 能访问键盘按键
.key
- ❗配合 as 断言指定为 input 标签类型,才可访问
.value
属性
const handleKeyup = (e:KeyboardEvent) =>{
console.log(e.key)
❗// 配合 as 断言指定为 input 标签类型,才可访问 .value 属性
;(e.target as HTMLInputElement).value
}
<input v-model="num" @keyup="handelChange" />
✨开发技巧:鼠标悬停事件,看类型提示
<button @click="handleClick">点击获取事件对象</button>
<input @keyup="handleKeyup" type="text" />
模板引用与TS
<input type="text" ref="inputRef" />
const inputRef = ref<HTMLInputElement>()
// const inputRef = ref<null| HTMLInputElement>(null)
// 组件挂载完毕后
onMounted(() => {
// 1.✅更安全的调用,分支判断(类型守卫)
// if (inputRef.value) {
// inputRef.value.focus()
// }
// 2.更安全的调用,可选链
// (?.) 可选操作符 允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。
// 参考文档:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Optional_chaining
inputRef.value?.focus()
// 3.类型断言的写法
(inputRef.value as HTMLInputElement).focus()
})
内置类型声明文件
✨Ctrl + 鼠标左键
来查看内置类型声明文件内容
分别查看:Math random Date getDate
这些内置的类型声明
第三方库类型声明文件
下载第三方包
yarn add axios
或者 npm i axios
- axios 自带类型声明文件,书写代码有提示
yarn add lodash
或者 npm i lodash
- lodash 源码通过JS写的,默认无类型声明文件
yarn add @types/lodash -D
或者 npm i @types/lodash -D
- lodash 的类型声明文件,DefinitelyTyped 开源提供
✨经验:
- 一般较为出名的第三方包,都会有开发者补全对应的类型声明文件
- 下载命令为 yarn add @types/包名 -D
import axios from 'axios'
import lodash from 'lodash'
// ✨ Ctrl + 鼠标左键,来查看类型声明文件内容,axios,create,baseURL
axios.create({
baseURL: '',
})
lodash.chunk(['a', 'b', 'c', 'd'], 2)
共享自定义类型声明文件
项目需求:
- 电商网站在很多的模块中都要用到商品信息类型
解决方案:
- 把共享的类型定义到独立的文件并导出,哪里需要导入即可
src/types/index.d.ts
导出
// 导出共享的类型 Goods
export interface Goods{
id:string
name:string
desc:string
price:number
}
导入使用
// 导入类型 Goods
import { Goods } from './types'
// 使用类型
const goods:Goods = {
id: '123',
name: '商品名称',
desc: '商品描述',
price: 99,
}