vue3 非父子传值

1)引入 getCurrentInstance

import { ref, onMounted, onUnmounted, getCurrentInstance } from "vue";
var vueProxy = getCurrentInstance();

2)监听与销毁

onMounted(() => {
  vueProxy.proxy.$mittBus.on('historyShowDetail', showDetail)
})

onUnmounted(() => {
  vueProxy.proxy.$mittBus.off('historyShowDetail')
})

3)监听到后执行的方法

const showDetail = () => {

}

4)另一个页面发送

import { ref, getCurrentInstance } from 'vue'
var vueProxy = getCurrentInstance();
const showDetail = () => {
  vueProxy.proxy.$mittBus.emit('historyShowDetail', {})
}
<think>嗯,用户想知道在Vue3中使用TypeScript实现父子组件的方法。首先,我得回忆一下Vue3的组合式API和TypeScript的结合方式。记得Vue3的setup语法糖确实简化了组件的编写,特别是用defineProps和defineEmits来声明props和事件。 首先,父子是通过props。在子组件里,需要用defineProps来定义接收的属性,而且TypeScript的话,可能需要用PropType来指定复杂类型。比如用户递一个对象,就需要用PropType来明确结构。然后父组件在使用子组件的时候,通过属性绑定递数据。 然后子父,应该使用自定义事件。子组件用defineEmits定义可以触发的事件,然后通过emit函数来触发,并递数据。父组件监听这些事件,并在自己的方法中处理数据。要注意的是,事件的定义需要符合TypeScript的类型要求,比如参数的类型和返回类型。 还有,用户可能对兄弟组件或者更深层次的组件通信感兴趣,不过这次问题主要是父子,所以可能需要提到其他方法比如mitt或者provide/inject,但重点还是在父子之间的props和事件。 还要注意代码示例的正确性,比如在子组件中使用泛型来定义props的类型,或者使用接口来规范对象结构。另外,引用中的资料提到避免直接修改props,所以在子组件中应该使用emit来让父组件修改数据,保持单向数据流。 可能用户需要具体的代码示例,比如父组件递一个字符串或者对象,子组件接收并显示,然后子组件触发事件修改父组件的数据。还要展示TypeScript的类型声明,比如使用接口和PropType。 最后,确保回答结构清晰,分步骤说明父子和子父的实现方法,并给出代码示例。同时,生成的相关问题要覆盖用户可能进一步想知道的内容,比如类型校验、复杂对象递、兄弟组件通信等。</think># Vue3 TypeScript 父子组件详解 ## 一、父子:Props ### 1. 子组件定义 ```typescript // Child.vue <script setup lang="ts"> interface User { name: string age: number } const props = defineProps<{ // 基础类型 title: string // 带默认 count?: number // 复杂对象类型 user: User // 函数类型 onUpdate?: () => void }>() </script> <template> <div> <h2>{{ title }}</h2> <p>Count: {{ count || 0 }}</p> <p>User: {{ user.name }} ({{ user.age }})</p> </div> </template> ``` ### 2. 父组件使用 ```typescript // Parent.vue <script setup lang="ts"> import Child from &#39;./Child.vue&#39; import { ref } from &#39;vue&#39; const userData = ref({ name: &#39;张三&#39;, age: 25 }) </script> <template> <Child title="用户信息" :count="10" :user="userData" /> </template> ``` **最佳实践:** - 使用 `interface` 定义复杂数据类型 - 可选参数使用 `?` 声明[^2] - 避免直接修改 props 数据 ## 二、子父:自定义事件 ### 1. 子组件定义 ```typescript // Child.vue <script setup lang="ts"> const emit = defineEmits<{ (e: &#39;update:title&#39;, value: string): void (e: &#39;submit&#39;, data: { id: number }): void }>() const handleClick = () => { emit(&#39;update:title&#39;, &#39;新标题&#39;) emit(&#39;submit&#39;, { id: 123 }) } </script> <template> <button @click="handleClick">提交</button> </template> ``` ### 2. 父组件监听 ```typescript // Parent.vue <script setup lang="ts"> const handleTitleUpdate = (newTitle: string) => { console.log(&#39;新标题:&#39;, newTitle) } const handleSubmit = (data: { id: number }) => { console.log(&#39;提交数据:&#39;, data.id) } </script> <template> <Child @update:title="handleTitleUpdate" @submit="handleSubmit" /> </template> ``` ## 三、双向绑定 ```typescript // 子组件 defineProps<{ modelValue: string }>() const emit = defineEmits<{ (e: &#39;update:modelValue&#39;, value: string): void }>() <input :value="modelValue" @input="emit(&#39;update:modelValue&#39;, ($event.target as HTMLInputElement).value)" > // 父组件 <Child v-model="inputValue" /> ``` ## 四、类型校验最佳实践 1. 使用 `PropType` 处理复杂类型: ```typescript import type { PropType } from &#39;vue&#39; defineProps({ user: { type: Object as PropType<User>, required: true } }) ``` 2. 事件参数类型验证: ```typescript defineEmits<{ (e: &#39;search&#39;, keyword: string): void (e: &#39;upload&#39;, file: File): void }>() ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值