vue3组合式API搭配TS类型推导

ref()

  • ref()接受一个内部值,返回一个响应式的、可更改的 ref 对象,此对象只有一个指向其内部值的property.value
  • 类型
    • 使用泛型 推荐
    • 使用接口
    • 使用Ref
// 使用泛型 推荐
import { ref } from 'vue'

const initCode = ref<string | number>('200')

// 使用interface
import { ref } from 'vue'

interface User {
  name: string
  age: string | number
}

const user = ref<User>({
  name:'前端开发爱好者',
  age: 20
})

reactive()

  • reactive() 返回一个对象的响应式代理。
  • 类型
    • 直接添加 推荐
    • 使用泛型
// 直接给声明的变量添加类型  推荐
import { reactive } from 'vue'

interface User {
  name: string
  age: string | number
}

const user:User = reactive({
  name:"前端开发爱好者",
  age:'20'
})

computed()

  • 接受一个 getter 函数,返回一个只读的响应式 ref 对象,即 getter 函数的返回值。它也可以接受一个带有 getset 函数的对象来创建一个可写的 ref 对象。
  • 类型
    • 根据返回值推导
    • 使用泛型 推荐
// 1 从其计算函数的返回值上推导出类型
import { ref, computed } from 'vue'

const count = ref<number>(0)

const user = computed(() => count.value + '前端开发爱好者')  // 推导的类型:ComputedRef<string>

// 2 通过泛型参数显式指定类型
const user = computed<string>(() => {
  return '前端开发爱好者'  // 若返回值不是 string 类型则会报错
})

defineProps()

  • 为了在声明 props 选项时获得完整的类型推断支持,我们可以使用 defineProps API,它将自动地在 script setup 中使用
  • 类型
    • 从参数中推导
    • 使用泛型
    • 使用接口
// 从参数中推导
const props = defineProps({
  name: { 
	type: String, 
	required: true
  },
  age: Number
})

 // 使用泛型
 const props = defineProps<{
  name: string
  age?: number
 }>()

// 使用接口
interface Props {
  name: string
  age?: number
}

const props = defineProps<Props>()
  • 以上的方式虽然都可以很方便的标注类型, 但是失去了对 props 定义默认值的能力
  • 故推荐使用withDefaults
    • 参数一定义props的类型
    • 参数二定义props的默认值
const props = withDefaults(
  defineProps<{
    title: string
    value: string
  }>(),
  {
    title: '你好世界',
    value: 'hello world'
  }
)

defineEmits()

  • 为了在声明 emits 选项时获得完整的类型推断支持,我们可以使用 defineEmits API,它将自动地在 script setup 中使用
  • 类型
    • 使用泛型
    • 子组件定义自定义事件
// 不使用TS
const emit = defineEmits(['hello', 'update:value'])

// 使用TS 泛型
const emit = defineEmits<{
  (e: 'hello', value: string): void
  (v: 'update:value', value: string): void
}>()

// 触发自身事件,提供自定义事件与携带参数
const toEmits = () => {
  emit('hello', state.name)
  emit('update:value', props.value)  // update:value 用于父子组件数据双向绑定
}
  • 父组件中接收
<template>
	...
	<Child  @hello="handleHello" /> // 监听自定义事件 hello
</template>

<script>
	const handleHello = (e: string, v: string) => {
	  state.msg = e
	  satte.value = v
	}
</script>

父子组件数据双向绑定

  • 我们可能会经常看到类似的代码v-model:title="bookTitle",在此补充下
  • v-model的相关说明,可参考官网:配合 v-model 使用
  • 由于props是单向数据流,如果你希望子组件的数据能够与父组件的数据进行双向绑定,那么就可以利用v-model

官网示例如下(略微改动过)

  • 子组件
// UserName.vue
<template>
  <input
    type="text"
    :value="firstName"  // 3 在子组件自身绑定props刚才定义的数据 firstName
    @input="$emit('update:firstName', $event.target.value)"
  />
  <input
    type="text"
    :value="lastName"  // 3 在子组件自身绑定props刚才定义的数据 lastName
    @input="$emit('update:lastName', $event.target.value)"
  />
</template>

<script setup>
// 1 定义props数据,实际建议使用上述defineProps()提到的使用"withDefaults"方法
defineProps({
  firstName: String,
  lastName: String
})

// 2 定义emit 格式:update:xxx  xxx就是props定义中定义的数据
defineEmits(['update:firstName', 'update:lastName']) 

// 4 在合适的时机,将数据emit给父组件
const transDate = () => {
  emit('update:firstName')
  emit('update:lastName')
}
</script>
  • 父组件
// 5 在父组件中,使用v-model绑定,至此子组件数据发生变化,父组件数据也会随之变化
<UserName v-model:first-name="first" v-model:last-name="last" />

defineExpose()

  • defineExpose() 编译器宏来显式指定在 script setup 组件中要暴露出去的 property,使得父组件通过模板ref的方式获取到当前组件的实例
  • 类型:使用参数类型自动推导
<script setup>
import { ref } from 'vue'

const name = ref<string>('前端开发爱好者')

defineExpose({
  name
})
</script>

更多类型标注参考,可访问官网vue3 使用教程vue3 使用指南

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值