vue3学习教程第三十二节(TS 之 ref reactive defineProps)

vue3 项目中TS常见用法之 ref() /reactive()/ defineProps() 使用的注意事项及用法

1、ref 创建的响应式对象 类型

vue3 文件中 当我们在 script 中添加 lang=“ts” 时候,编译模板会自动根据script 中定义的数据类型而推断出属性的类型(当没有声明属性类型时候)
比如:
以下单文件

<template>
  <div class="my-ts">
    This is a demo of TS.
    <h3>{{ name }}</h3>
  </div>
</template>
<script setup lang="ts">
import { ref } from "vue"
const name =  ref(333)
</script>

请添加图片描述
请添加图片描述

注意:在使用时候类型定义要与调用的方法保持一致,不然会导致对应的属性 没有该方法而报错;
比如:

<template>
  <div class="my-ts">
    This is a demo of TS.
    <h3>{{ name }}</h3>
    <el-button @click="handleChangeName">change name</el-button>
  </div>
</template>
<script setup lang="ts">
import { ref } from "vue"
const name =  ref<string | number>(333)
const handleChangeName = ():void => {
  name.value.toFixed(2)
  console.log()
}
</script>

name.value.toFixed(2) 由于string 类型的属性是没有 toFixed() 方法的,故报错,如下图
请添加图片描述

若不想修改 初始化中的数据类型,则需要如下修改

<script setup lang="ts">
import { ref } from "vue"
const name =  ref<string | number>(333)
const handleChangeName = ():void => {
    // 将name.value 的 值断言为  number 类型
//   (name.value as number).toFixed(2)
    //   或者直接重新赋值为 number类型
    name.value = 4.67890
    const curName: string | number = name.value.toFixed(3)
  console.log('curName',curName)
}
</script>

当我们给ref 指定复杂类型时候,通过Ref 类型声明或者调用 ref时传入一个泛型参数 来覆盖推断类型

import type {Ref} from "vue"
const age: Ref< String | Number> = ref(18)

如果泛型参数没有给定初始值,那么会得到一个undefined 类型

2、reactive() 创建对象的类型

reactive 创建的响应式,只能是对象类型,不能是基本类型;

创建对象类型:

<script lang="ts" setup>
import { reactive } from "vue"
// 对象
interface Person {
  name: string;
  age: number;
  job?: string; // 可选属性,即该属性可有可无
  changeJob: () => void;
}
const preson: Person = reactive({
  name: 'Andy',
  age: 18,
  changeJob: () => {
    preson.job = '专业搬砖'
  }
})
</script>

创建数组对象

<script setup lang="ts">

// 数组
// 先声明对象中的各个属性的类型,

interface Item {
  id: number;
  name: string;
}
// 声明 index 的类型
interface Lists {
  [index: number]: Item
}

const lists: Lists = reactive([
  {
    id: 1,
    name: 'Andy'
  },
  {
    id: 2,
    name: 'Tom'
  },
  {
    id: 3,
    name: 'Jerry'
  }
])
</script>

3.1、props 中的类型声明

<script setup lang="ts">
// 没有使用ts 的类型声明
const props = defineProps({
    person: {
        type: Object,
        default: () => ({})
    }
})
// 使用ts时
// 定义 Person 接口
interface Person{
  name: string;
  age: {
    type: number,
    required: true
  };
  job?: string; // 可选属性,即该属性可有可无
  changeJob: () => void;

}
interface AgeIn {
  age: number | string // 联合声明 age
}
const props = defineProps<{
  person: Person,
  age: AgeIn
}>()

// 当需要给默认值的时候,需要使用 widthDefaults() 
// withDefaults 辅助函数提供了对默认值的类型检查,并确保返回的 props 的类型删除了已声明默认值的属性的可选标
// defineProps 在一个script 中只能调用一次,不能调用多次
// const ageProps = withDefaults(defineProps<AgeIn>(), {
//   age: 12
// })
// 传递给 defineProps 的参数本身不能是一个导入类型, 只能是当前文件下的一个对象或者interface
</script>

3.2、当一个组件需要传递不同的数据结构和类型时候

父组件向子组件传递的所有参数中,基本类型、复杂类型参数都有的情况下:
首先定义一个接口 Props ,
其次使用 withDefaults() 检查默认值
若为 复杂类型数据,需要使用 箭头函数 return 出去各个子属性的默认值

<script lang="ts" setup>
interface Props {
  either: '必传且限定'|'其中一个'|'值', // 利用TS:限定父组件传 either 的值
  child: string|number,
  sda?: string, // 未设置默认值,为 undefined
  strData: string,
  msg?: string
  labels?: string[],
  obj?:{name:string, age?: number}
}
const props = withDefaults(defineProps<Props>(), {
  msg: 'hello',
//  复杂类型需要 return 出来默认值  
  labels: () => ['one', 'two'],
  obj: () => { return {name: 'Andy', age:2} }
})
console.log('==props==', props)
</script>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刺客-Andy

努力将爱好变成更有价值的事物

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值