Vue3-兄弟组件传参和Bus
1、通过父组件作为传输参数的媒介
父组件通过props向子组件传输自另一个子组件中接收到的参数,操作麻烦,无法直接通信,只能充当桥梁
父组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| <!-- * @Description: * @Author: xiuji * @Date: 2022-08-31 21:14:30 * @LastEditTime: 2022-10-24 17:29:06 * @LastEditors: Do not edit --> <template> <div class="content"> <SA @on-click="getParams"></SA> <SB :params="params"></SB> </div> </template>
<script setup lang="ts"> import SA from './components/SA.vue' import SB from '@/layout/content/components/SB.vue' import { ref } from 'vue' let params = ref(false) const getParams = (item: boolean) => { params.value = item }
</script>
<style lang="scss" scoped> .content { position: relative; flex: 1; height: 100%; margin: 20px; border: 1px solid #ccc; overflow: auto;
} </style>
|
子组件A
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <!-- * @Description: * @Author: xiuji * @Date: 2022-10-24 16:08:13 * @LastEditTime: 2022-10-24 17:29:49 * @LastEditors: Do not edit --> <template> <div class="A"> <h1>A</h1> <button @click="change">change</button> </div> </template>
<script setup lang="ts"> import { ref } from 'vue' let aValue = false const emit = defineEmits(['on-click']) const change = () => { aValue = !aValue emit('on-click', aValue) } </script>
<style scoped> .A { width: 200px; height: 200px; background-color: aquamarine; } </style>
|
子组件B
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <!-- * @Description: * @Author: xiuji * @Date: 2022-10-24 16:08:19 * @LastEditTime: 2022-10-24 17:29:14 * @LastEditors: Do not edit --> <template> <div class="B"> <h1>B</h1> <div>{{ params}}</div> </div> </template>
<script setup lang="ts"> type Props = { params?: boolean }
defineProps<Props>() </script>
<style scoped> .B { width: 200px; height: 200px; background-color: greenyellow; } </style>
|
此种方式可以实现兄弟组件传参,但是非常繁琐
2、Event Bus
通过自定义事件中心简化传参
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
|
type busClass = { on: (name: string, Fn: Function) => void emit: (name: string) => void }
type paramsKey = string | number | symbol
type List = { [key: paramsKey]: Array<Function> }
class Bus implements busClass { list: List constructor() { this.list = {} } on(name: string, callback: Function) { let fn: Array<Function> = this.list[name] || [] fn.push(callback) this.list[name] = fn } emit(name: string, ...args: Array<any>) { let eventName: Array<Function> = this.list[name] eventName.forEach(fn => { fn.apply(this, args) }) } }
export default new Bus()
|
子组件A导入Bus并通过emit派发事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <!-- * @Description: * @Author: xiuji * @Date: 2022-10-24 16:08:13 * @LastEditTime: 2022-11-10 15:45:23 * @LastEditors: Do not edit --> <template> <div class="A"> <h1>A</h1> <button @click="change">change</button> </div> </template>
<script setup lang="ts"> import Bus from '../../../bus' let aValue = false const change = () => { aValue = !aValue Bus.emit('on-click', aValue) } </script>
<style scoped> .A { width: 200px; height: 200px; background-color: aquamarine; } </style>
|
子组件B导入Bus并通过on收事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <!-- * @Description: * @Author: xiuji * @Date: 2022-10-24 16:08:19 * @LastEditTime: 2022-11-10 15:37:56 * @LastEditors: Do not edit --> <template> <div class="B"> <h1>B</h1> <div>{{ flag }}</div> </div> </template>
<script setup lang="ts"> import { ref } from 'vue'; import Bus from '../../../bus' let flag = ref(false) Bus.on('on-click', (params: boolean) => { flag.value = params }) </script>
<style scoped> .B { width: 200px; height: 200px; background-color: greenyellow; } </style>
|
如此可以省去父组件在兄弟组件传参中的桥梁作用