vue3兄弟组件传值

110 阅读1分钟

vue原始方式:通过emit事件、父组件props进行中转

一、父组件下属两个子组件

parent.vue

<template>
    <div class="flex">
    <childEVue @post="receive"></childEVue>
    <childFVue :num = "receiveNum"></childFVue>
    </div>
</template>

<script setup lang='ts'>
import childEVue from '../example/childE.vue';
import childFVue from '../example/childF.vue';
import {ref} from 'vue';
let receiveNum = ref(0)
const receive = (param:any)=>{
    console.log(param.value)
    receiveNum.value = param.value
}


</script>

<style scoped>
.flex {
    display: flex;
}
</style>

子组件childEVue

<template>
        <div class="ce-box">
        <button @click="postMessage">  
            子组件  发射部分 {{count}}
        </button>
     
        </div>
</template>
    
<script setup lang='ts'>
import {ref} from 'vue'
const emit = defineEmits([ 'post'])
const count = ref(0)
 const postMessage = () =>{
    count.value = count.value + 1
    
    emit('post',count)
    console.log("子组件发射部分触发")
 }
</script>
    
<style scoped>
.ce-box {
    width: 200px;
    height: 200px;
    background-color: aqua;
}
</style>


子组件childFVue

<template>
    <div class="ce-box">
    <button>  
        子组件  被改变部分{{num}}
    </button>
 
    </div>
</template>

<script setup lang='ts'>
defineProps({
  num: Number
})
</script>

<style scoped>
.ce-box {
width: 200px;
height: 200px;
background-color: aqua;
margin-left: 200px;
}
</style>

效果:

mitt方式

官方推荐的vue3事件总线方式:mitt

实现方式:

  1. 安装

npm install mitt -S

main.ts中全局挂载

import { createApp } from 'vue'
import App from './App.vue'
import mitt from 'mitt'

const Mit = mitt()

//TypeScript注册
// 由于必须要拓展ComponentCustomProperties类型才能获得类型提示
declare module "vue" {
    export interface ComponentCustomProperties {
        $Bus: typeof Mit
    }
  
  }

const app = createApp(App)
app.config.globalProperties.$Bus = Mit

app.mount('#app')

  1. 两个子组件

childE.vue

<template>
        <div class="ce-box">
        <button @click="postMessage">  
            子组件  发射部分 {{count}}
        </button>

        <div class="mittp">
            <button @click="mittEmit">mitt发射子组件{{newCount}}</button>
        </div>
     
        </div>
</template>
    
<script setup lang='ts'>
import {ref} from 'vue'
import { getCurrentInstance } from 'vue'
const emit = defineEmits([ 'post'])
const count = ref(0)
const newCount = ref(0)
 const postMessage = () =>{
    count.value = count.value + 1

    emit('post',count)
    console.log("子组件发射部分触发")
 }

const instance = getCurrentInstance(); 

 const mittEmit = ()=>{
    newCount.value += 10
    instance?.proxy?.$Bus.emit('on-num', newCount) 
 }
</script>
    
<style scoped>
.ce-box {
    width: 200px;
    height: 200px;
    background-color: aqua;
}

.mittp{
    font-size: 30px;
}
</style>

childF.vue

<template>
    <div class="ce-box">
    <button>  
        子组件  被改变部分{{num}}
    </button>

    <div class="mittr">
        <button>  
        子组件 mitt 被改变部分{{showNum}}
    </button>
    </div>
 
    </div>
</template>

<script setup lang='ts'>
import { getCurrentInstance, ref } from 'vue'
const instance = getCurrentInstance()
const showNum:any = ref("")
instance?.proxy?.$Bus.on('on-num', (num) => {
    console.log(num,'===========>B')
    showNum.value = num
}) 
defineProps({
  num: Number
})


</script>

<style scoped>
.ce-box {
width: 200px;
height: 200px;
background-color: aqua;
margin-left: 200px;
}

.mittr{
    margin-top: 20px;
}
</style>

效果: