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,
}