Vue3组件通信(全)

目录:

1. 父传子

2. 子传父

3. 兄弟组件

4. 祖孙通信


1. 父传子

// 父组件
<Children :data="data"></Children>
<script>
 import { ref, reactive } from 'vue'
    const data = reactive({
        name: '张三',
        age: 20,
        hoppy: ['打球', '唱歌']
    })
</script>

// 子组件
<template>
    <div>{{ data }}</div>
</template>
<script setup lang="ts">
 import { ref, reactive } from 'vue'
// 1.搭配ts写法
type Props = {
    name?: string,
    age: number,
    hoppy?: string[]
}
defineProps<Props>()  // 可以直接使用defineProps接收,不需要引入

// 2.单独写法
defineProps({      
    data: Object,
})

// 3.如果需要默认值用下面写法
withDefaults(defineProps<Props>(), {
    name: '我是默认值',
    age: 20,
    hoppy: ()=> ["吃手手"] // 引用数据类型需要使用函数返回
})
</script>

2. 子传父

// 父组件
<Children @send-list="getList" @send-list2="getList2" :data="data"></Children>
<script>
 import { ref, reactive } from 'vue'
    const data = reactive({
        name: '张三',
        age: 20,
    })
    const getList = (val, flag)=>{
		console.log(val, flag)
    }
    const getList2 = (val)=>{
		console.log(val)
    }
</script>

// 子组件
<template>
    <div>{{ data }}</div>
	<button @click="send">发送1</button>
	<button @click="send2">发送2</button>
</template>
<script setup lang="ts">
 import { ref, reactive } from 'vue'
    defineProps({      // 可以直接使用defineProps接收,不需要引入
        data: Object,
    })
const list = reactive([1,2,3])
const list2 = reactive([4,5,6])

// 可以传单个或者多个,用数组标识
const emit = defineEmits(['send-List', 'send-List2']) 
const send = ()=>{
    emit('send-List', list, true)
}
const send2 = ()=>{
    emit('send-List2', list2)
}
</script>

3. 兄弟组件

// 1.使用mitt库
npm i mitt -S

// 2.手写一个Bus
// Bus.ts
type BusClass = {
    emit:(name: string)=>void
    on:(name: string, callback: Function)=>void
}
    
type ParamsKey = string | number | symbol

type List = {
    [key: ParamsKey]: Array<Function>
}
    
class Bus implements BusClass {
    list: List
    constructor(){
        this.list = {}
    }
	emit(name: string, ...args: Array<any>){
        let eventName: Array<Function> = this.list[name]
        eventName.forEach(fn=>{
            fn.apply(this, args)
        })
	}
	on(name: string, callback: Function){
		let fn: Array<Function> = this.list[name] || []
        fn.push(callback)
        this.list[name] = fn
    }
}
export default new Bus()

// 使用
// A.vue
import Bus from 'Bus.ts'
Bus.emit('name', name)

// B.vue
import Bus from 'Bus.ts'
Bus.on('name', (val)=>{
    console.log(val)
})

4. 祖孙通信

// 1、祖组件:
setup(){
    let car = reactive({
      name:'car',
      price:188888
    })
    provide('car',car)//给自己的后代组件传递数据
    return {
      ...toRefs(car)
    }
}

// 2、后代组件
setup(){
    let car = inject('car') // 使用inject接收
    return{
        car
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值