TS在vue中的应用

TIP

typescript 配合 Vue3 composition-api 使用

TypeScript 与组合式 API | Vue.js

script 加上 lang="ts" 才能写ts代码

<script setup lang="ts"></script>

defineProps的TS写法

1. defineProps 的基本使用:

const props = defineProps({
  money: {
    type: Number,
    required: true
  },
  car: {
    type: String,
    required: false,
    default: '宝马车'
  }
})
console.log(props.money) // number
console.log(props.car) // string | undefined

2. defineProps 通过泛型参数来定义 props 的类型通常更直接:

const props = defineProps<{
  money: number
  car?: string
}>()

我们也可以将 props 的类型移入一个单独的接口中: 

<script setup lang="ts">
interface Props {
  foo: string
  bar?: number
}

const props = defineProps<Props>()
</script>

 3. 给 props 设置默认值

可以使用 响应式语法糖https://cn.vuejs.org/guide/extras/reactivity-transform.html#reactive-props-destructure 解构 + defineProps 就行

const { money, car = "宝马车" } = defineProps<{
  money: number
  car?: string
}>();

但是,这个响应式语法糖需要显示地选择开启 reactivityTransform, 因为它还是一个实验性特性显式地选择开启https://cn.vuejs.org/guide/extras/reactivity-transform.html#explicit-opt-in响应性语法糖 | Vue.js

// vite.config.ts
export default defineConfig({
  plugins: [
    vue({
      reactivityTransform: true,
    }),
  ],
});

 需要给 props 设置默认值,也可以使用 withDefaults 函数:但是这种写法比较笨拙

const props = withDefaults(defineProps<{
  money: number;
  car?: string;
}>(),{
  car: '宝马车'
})
// 第二个对象中是设置默认值的,了解

注意:

接口或对象字面类型可以包含从其他文件导入的类型引用,但是,传递给 defineProps 的泛型参数本身不能是一个导入的类型:这是因为 Vue 组件是单独编译的,编译器目前不会抓取导入的文件以分析源类型。

import { Props } from './other-file'

// 不支持!
defineProps<Props>()

defineEmits的TS写法

1. defineEmits 的基本用法:

const emit = defineEmits(['changeMoney', 'changeCar'])

2. defineEmits 通过泛型参数来定义,可以实现更细粒度的校验:

const emit = defineEmits<{
  (e: 'changeMoney', money: number): void
  (e: 'changeCar', car: string): void
}>()

emit('changeMoney', 10 )
emit('changeCar',  '10')

ref的TS写法

ref() 会隐式的依据数据推导类型

1. 如果是简单类型,推荐使用类型推导:

const money = ref(10)

2. 如果是复杂类型,推荐指定泛型:

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 }
  ]
}, 1000)

reactive的TS写法

reactive() 也会隐式的依据数据推导类型

1. 默认值属性是固定的,推荐使用类型推导:

// 推导得到的类型:{ title: string }
const book = reactive({ title: 'Vue3 在线医疗' })  

2.  默认值推导不出需要的类型:

推荐使用接口或者类型别名给变量指定类型

  • 官方:不推荐使用 reactive() 的泛型参数,因为底层和 ref() 实现不一样。
// 我们想要的类型:{ title: string, year?: number }
type Book = {
  title: string
  year?: number
}
const book: Book = reactive({ title: 'Vue3 在线医疗' })
book.year = 2022

computed和TS

computed() 会从其计算函数的返回值上推导出类型

import { ref, computed } from 'vue'

const count = ref(100);
const doubleCount = computed(() => count.value * 2);

可以通过泛型参数显式指定类型

const doubleMoney = computed<string>(() => (count.value * 2).toFixed(2));

事件处理与TS

不加类型,event默认是any,类型不安全:

<script setup lang="ts">
// 提示:参数“event”隐式具有“any”类型。  
const handleChange = (event) => {
  console.log(event.target.value)
}
</script>

<template>
  <input type="text" @change="handleChange" />
</template>

 处理类型:document.querySelector('input') 查看返回值类型

// `event` 隐式地标注为 `any` 类型,如何指定:event 类型?
// 1. @change="handleChange($event)"" 查看$event类型
// 2. 鼠标摸一下事件 @change 查看类型
const handleChange = (event: Event) => {
  // `event.target` 是 `EventTarget | null` 类型,如何指定具体类型?
  // document.querySelector('input') 查看返回值类型
  console.log((event.target as HTMLInputElement).value)
}

Template Ref与TS

模板 ref 需要通过一个显式指定的泛型参数,建议默认值 null

<script setup lang="ts">
import { ref, onMounted } from 'vue'

const el = ref<HTMLInputElement| null>(null)

onMounted(() => {
  el.value?.focus()
})
</script>

<template>
  <input ref="el" />
</template>
  • 注意为了严格的类型安全,有必要在访问 el.value 时使用可选链或类型守卫。
  • 这是因为直到组件被挂载前,这个 ref 的值都是初始的 null,并且在由于 v-if 的行为将引用的元素卸载时也可以被设置为 null

非空断言

处理类型可能是 null 或 undefined 的值,下面的属性或函数的访问赋值:

1. 可选链  -只能访问

<script setup lang="ts">
import { onMounted, ref } from 'vue';


const input = ref< HTMLInputElement | null >(null)

onMounted(()=>{
  // 只能访问
  console.log(input.value?.value);
})

</script>

<template>
  <div>App组件</div>
  <input type="text" ref="input" value="abc">
</template>

 2. 逻辑判断

 if (input.value) {
    console.log(input.value.value)
    input.value.value = '123'
  }

3. 非空断言

  // 一定要确定不为空!!!
  console.log(input.value!.value)
  input.value!.value = '123'

猜你喜欢

转载自blog.csdn.net/luoxiaonuan_hi/article/details/130008552
今日推荐