defineProps、defineEmits、 defineExpose的TS写法

小满视频
在这里插入图片描述

1 defineProps:父向子传递数据

作用:父组件向子组件传递数据

1.1 传递纯类型参数的方式来声明

父组件中的代码:

父组件App.vue
<template>
  <div>
    <span>传递给子组件的响应式数据:</span><input type="text" v-model="sendData">
    <hr>
    <!-- 2. 使用子组件,添加要传递的数据 -->
    <props :sendData="sendData" a="非响应式数据"></props>
  </div>
</template>

<script setup lang="ts">
import {ref} from 'vue'
// 1. 引入子组件props
import props from './components/props.vue'
const sendData = ref('')

</script>

子组件代码:

子组件props.vue
<template>
  <div>
    <p>子组件接收到的数据:</p>
    <!-- 4. 插值语法,使用子组件数据 -->
    <p>非响应式:{{ a }}</p>
    <p>响应式:{{ sendData }}</p>
  </div>
</template>

<script setup lang="ts">
import {defineProps} from 'vue'
// 3. 使用defineProps接受父组件传递来的数据
defineProps<{
  a:string,
  sendData:string
}>()
</script>

在这里插入图片描述

1.2 传递数据设置默认值

父组件代码:

父组件App.vue
<template>
  <div>
    <span>传递给子组件的响应式数据:</span><input type="text" v-model="sendData">
    <hr>
    <!-- 2. 使用子组件,添加要传递的数据 -->
    <props :sendData="sendData" a="非响应式数据"></props>
  </div>
</template>

<script setup lang="ts">
import {ref} from 'vue'
// 1. 引入子组件props
import props from './components/props.vue'
const sendData = ref() // 为了演示默认值,修改了这里,在ts中应该指定类型 

</script>


子组件代码:

子组件props.vue
<template>
  <div>
    <p>子组件接收到的数据:</p>
    <!-- 4. 插值语法,使用子组件数据 -->
    <p>非响应式:{{ a }}</p>
    <p>响应式:{{ sendData }}</p>
  </div>
</template>

<script setup lang="ts">
import {defineProps} from 'vue'
// 3. 使用defineProps接受父组件传递来的数据
// 只有在使用ts时才能使用withDefaults
withDefaults(defineProps<{
  a:string,
  sendData:string
}>(),{
  sendData:'默认值'
})
</script>


在这里插入图片描述

2 defineEmits:子组件执行父组件中的函数,可在通过函数参数传递数据

2.1 使用defineEmits定义事件

子组件代码:

子组件son1.vue
<template>
    <div>
        子组件<br>
        <input type="text" v-model="msg1"><br>
        <input type="text" v-model="msg2"><br>
        <!-- 2. 定义一个点击事件 -->
        <button @click="sendToF">第一种发送方式</button>
        <!-- 或者第2步和第3步写在一起. 直接在@click事件中使用emit触发事件clickSend,并传递参数 -->
        <button @click="emit('clickSend',[msg1,msg2])">第二种发送方式</button>
    </div>
</template>

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

const msg1 = ref<string>('')
const msg2 = ref<string>('')
// 1. 使用defineEmits定义一个事件名称
const emit = defineEmits(['clickSend'])

// 3. 在点击事件中使用emit触发事件clickSend,并传递参数
const sendToF = () => {
    emit('clickSend',msg1.value)
}
</script>

父组件代码:

父组件App.vue
<template>
    <div>
        父组件
        <div>子组件传来的数据:{{ getData }}</div>
        <hr>
        <!-- 4. 在父组件中使用@符号绑定子组件中的定义的事件 -->
        <son1 @clickSend="son1Data"></son1>
        
    </div>
</template>

<script setup lang="ts">
import { ref } from "vue";
import Son1 from "./components/son1.vue";
const getData = ref<string>('')
// 5. 事件触发后,参数中的值就是子组件传过来的值
const son1Data = (data:string) => {
  getData.value = data
}
</script>

第一种发送方式只发送了一个字符串
第二种发送方式发送了一个数组

在这里插入图片描述

2.2 传递纯类型参数的方式来声明

子组件代码:

子组件son1.vue
<template>
  <div>
    子组件<br />
    <input type="text" v-model="msg1" /><br />
    <input type="text" v-model="msg2" /><br />
    <button @click="sendToF">发送</button>
  </div>
</template>

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

const msg1 = ref<number|"">("");
const msg2 = ref<string>("");
// ts的定义方式
const emit = defineEmits<{
  change: [msg1: number|""]; // 具名元组语法
  update: [msg2: string];
}>();
// ts的另一种定义方式
/*
const emit = defineEmits<{
  (e: 'change', id: number): void
  (e: 'update', value: string): void
}>()
*/
const sendToF = () => {
    emit("change", msg1.value);
    emit("update", msg2.value);
}
</script>

父组件代码:

父组件App.vue
<template>
    <div>
        父组件:
        <div>子组件第一个参数:{{ getData1 }}</div>
        <div>子组件第二个参数:{{ getData2 }}</div>
        <hr>
        <!-- 4. 在父组件中使用@符号绑定子组件中的定义的事件 -->
        <son @change="msg1" @update="msg2"></son>
        
    </div>
</template>

<script setup lang="ts">
import { ref } from "vue";
import Son from "./components/son.vue";
const getData1 = ref<number|"">("")
const getData2 = ref<string>()
const msg1 = (msg: number|"") => {
    getData1.value = msg
}
const msg2 = (msg: string) => {
    getData2.value = msg
}
</script>

3 defineExpose:子向父暴露

  • 默认情况下,就算通过引用可以获取到子组件实例,也没有办法获取到子组件中定义的属性和方法
  • 子组件可以主动的向外暴露自己的属性和方法

子组件代码

子组件props.vue
<template>
    <div>
        子组件
    </div>
</template>

<script setup lang="ts">
import { ref } from "vue";
const sonData = ref("子组件数据");
const sonFun = () => {
    console.log("子组件方法");
}
// 1. 子组件向外暴露组件中的数据和方法
defineExpose({
    sonData,
    sonFun,
    changeSonData: () => {
        sonData.value = "子组件暴露的数据被修改";
    }
})
</script>

父组件代码:

父组件App.vue
<template>
  <div>
    <!-- 4. 使用子组件的数据 -->
    子组件向外暴露的数据:{{ sonVue?.sonData }}
    <br>
    <!-- 4. 调用子组件的方法,修改子组件的数据,在父组件中无法直接修改子组件的数据 -->
    <button @click="sonVue?.changeSonData()">修改子组件数据</button>
    <hr>
    <!-- 2. 通过ref属性将sonVue与Son组件关联起来 -->
    <Son ref="sonVue"></Son>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from "vue";
import Son from "./components/son.vue";
// 3. 使用ref创建一个指向Son组件实例的引用
const sonVue = ref<InstanceType<typeof Son>>();

onMounted(() => {
  // 4. 直接调用子组件方法需要在组件被挂载完毕的时候调用
  sonVue.value?.sonFun();
});
</script>

const sonVue = ref<InstanceType< typeof Son>>();
1. Son: 子组件。
2. typeof Son: 表示 Son 组件的类型。
3. InstanceType< typeof Son>: 获取 Son 组件实例的类型。
4. ref<InstanceType< typeof Son>>: 创建一个响应式的引用,其值将是 Son 组件的一个实例。

在 Vue 中,InstanceType 是一个 TypeScript 的实用工具类型,它用于获取类 T 的实例类型。当你定义了一个 Vue 组件并通过 ref 来持有这个组件的实例时,可以使用 InstanceType 来准确地指定类型的实例。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值