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
函数的返回值。它也可以接受一个带有get
和set
函数的对象来创建一个可写的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>