在vue3里,组件是一个非常重要的概念,项目中各个组件间的通信也是一个非常常见的需求,接下来我将为大家展示vue3组件有哪几种常见的通信方式。
一、props
适用场景:父子组件之间的通信
父传子:
父组件在子组件的标签中通过写属性名加属性值的方式,可以直接将数据传递给子组件(要想数据是响应式,必须使用通过v-bind,或其简写形式)
<template><div class="father"><h3>父组件</h3><h4>汽车:{{ car }}</h4><Child :car="car" /></div>
</template><script setup lang="ts" name="Father">
// @ts-ignoreimport Child from './Child.vue'import {ref} from 'vue'// 数据let car = ref('奔驰')
</script><style scoped>.father{background-color:rgb(165, 164, 164);padding: 20px;border-radius: 10px;}
</style>
子组件需要通过defineProps接收参数
<template><div class="child"><h3>子组件</h3><h4>玩具:{{ toy }}</h4><h4>父组件的车:{{ car }}</h4></div>
</template><script setup lang="ts" name="Child">import {ref} from 'vue'// 数据let toy = ref('奥特曼')// 声明接收propsdefineProps(['car'])
</script><style scoped>.child{background-color: skyblue;padding: 10px;box-shadow: 0 0 10px black;border-radius: 10px;}
</style>
效果:
子传父:
需要父组件先传递一个函数给子组件,子组件调用函数并传递参数
父组件传递了一个叫做sendToy的数据,其中的值是父组件的getToy函数
<template><div class="father"><h3>父组件</h3><h4>汽车:{{ car }}</h4><h4 v-show="toy">子给的玩具:{{ toy }}</h4><Child :car="car" :sendToy="getToy"/></div>
</template><script setup lang="ts" name="Father">
// @ts-ignoreimport Child from './Child.vue'import {ref} from 'vue'// 数据let car = ref('奔驰')let toy = ref('')// 方法function getToy(value:string){toy.value = value}
</script><style scoped>.father{background-color:rgb(165, 164, 164);padding: 20px;border-radius: 10px;}
</style>
子组件接收了sendToy数据,并在调用了函数时传递了参数
<template><div class="child"><h3>子组件</h3><h4>玩具:{{ toy }}</h4><h4>父组件的车:{{ car }}</h4><button @click="sendToy(toy)">把玩具给父组件</button></div>
</template><script setup lang="ts" name="Child">import {ref} from 'vue'// 数据let toy = ref('奥特曼')// 声明接收propsdefineProps(['car','sendToy'])
</script><style scoped>.child{background-color: skyblue;padding: 10px;box-shadow: 0 0 10px black;border-radius: 10px;}
</style>
效果:
点击按钮,子组件将会传递toy给父组件,父组件并会显示出文字
二、自定义事件
适用场景:子组件向父组件传递数据
示例:
父组件需要给子组件绑定自定义事件,并指定事件触发时将要执行的回调函数,send-toy 为子组件Child的事件名 ,saveToy为事件触发时的回调函数,参数为子组件传递的值
<template><div class="father"><h3>父组件</h3><h4 v-show="toy">子给的玩具:{{ toy }}</h4><!-- 给子组件Child绑定事件 --><!-- send-toy 为子组件Child的事件名 ,saveToy为事件触发时的回调函数,参数为子组件传递的值 --><Child @send-toy="saveToy"/></div>
</template><script setup lang="ts" name="Father">
// @ts-ignoreimport Child from './Child.vue'import { ref } from "vue";// 数据let toy = ref('')// 用于保存传递过来的玩具function saveToy(value:string){console.log('saveToy',value)toy.value = value}
</script><style scoped>.father{background-color:rgb(165, 164, 164);padding: 20px;border-radius: 10px;}.father button{margin-right: 5px;}
</style>
子组件需要声明事件,并选择在合适的时机通过emit触发事件
<template><div class="child"><h3>子组件</h3><h4>玩具:{{ toy }}</h4><button @click="emit('send-toy',toy)">测试</button></div>
</template><script setup lang="ts" name="Child">import { ref } from "vue";// 数据let toy = ref('奥特曼')// 声明事件const emit = defineEmits(['send-toy'])
</script><style scoped>.child{margin-top: 10px;background-color: rgb(76, 209, 76);padding: 10px;box-shadow: 0 0 10px black;border-radius: 10px;}
</style>
效果:
点击按钮将触发自定义事件,父组件接收到子组件传递的数据
三、mitt
适用场景:可以实现任意组件之间的通信
需要提前安装好mitt,并配置好mitt
emiter.ts:
javascript">// 引入mitt
import mitt from 'mitt'// 调用mitt得到emitter,emitter能:绑定事件、触发事件
const emitter = mitt()// 暴露emitter
export default emitter
兄弟组件:
<template><div class="child1"><h3>子组件1</h3><h4>玩具:{{ toy }}</h4><button @click="emitter.emit('send-toy',toy)">玩具给弟弟</button></div>
</template><script setup lang="ts" name="Child1">import {ref} from 'vue'// @ts-ignoreimport emitter from '@/utils/emitter';// 数据let toy = ref('奥特曼')
</script><style scoped>.child1{margin-top: 50px;background-color: skyblue;padding: 10px;box-shadow: 0 0 10px black;border-radius: 10px;}.child1 button{margin-right: 10px;}
</style>
<template><div class="child2"><h3>子组件2</h3><h4>电脑:{{ computer }}</h4><h4>哥哥给的玩具:{{ toy }}</h4></div>
</template><script setup lang="ts" name="Child2">import {ref,onUnmounted} from 'vue'// @ts-ignoreimport emitter from '@/utils/emitter';// 数据let computer = ref('联想')let toy = ref('')// 给emitter绑定send-toy事件emitter.on('send-toy',(value:any)=>{toy.value = value})// 在组件卸载时解绑send-toy事件onUnmounted(()=>{emitter.off('send-toy')})
</script><style scoped>.child2{margin-top: 50px;background-color: orange;padding: 10px;box-shadow: 0 0 10px black;border-radius: 10px;}
</style>
emitter使用on来绑定事件、emit来触发事件、off来解绑事件、clear清空绑定的所有事件
效果:
点击之后将传递数据给兄弟组件,并在兄弟组件中显示数据