Vue3中的常見組件通信之mitt使用詳解
Vue3中的常見組件通信之mitt
概述
? 在vue3中常見的組件通信有props、mitt、v-model、 refs、parent、provide、inject、pinia、slot等。不同的組件關(guān)系用不同的傳遞方式。
常見的撘配形式如下表所示。
| 組件關(guān)系 | 傳遞方式 |
|---|---|
| 父傳子 | 1. props 2. v-model 3. $refs 4. 默認(rèn)插槽、具名插槽 |
| 子傳父 | 1. props 2. 自定義事件 3. v-model 4. $parent 5. 作用域插槽 |
| 祖?zhèn)鲗O、孫傳祖 | 1. $attrs 2. provide、inject |
| 兄弟間、任意組件間 | 1. mitt 2. pinia |
? props和自定義事件詳見本人另一篇文章:
下面接著上文來繼續(xù)記錄mitt的用法。
mitt
mitt與pubsub訂閱消息與發(fā)布消息功能類似,它可以實(shí)現(xiàn)在任意組件間的通信。
安裝mitt及引入mitt
mitt需要安裝,在終端中輸入命令npm i mitt來安裝。
mitt安裝好之后按照工程化的管理需要在src的文件下新建文件夾utils,然后在utils文件夾中新建文件emitter.ts。
在emitter.ts文件中引入mitt,并創(chuàng)建emitter,同時暴露emitter,如下代碼:
//引入mitt import mitt from 'mitt' //調(diào)用mitt,得到emitter,emitter可以綁定事件和觸發(fā)事件 const emitter = mitt() //暴露emitter export default emitter
之后需要再在main.ts中引入emitter,如下代碼:
import emitter from '@/utils/emitter'
emitter基本用法
emitter身上有四個方法,分別是
- **on()??*用來綁定事件,接收兩個參數(shù),第一個參數(shù)是事件名,第二個參數(shù)是事件觸發(fā)時的回調(diào)函數(shù);
- **emit()??*用來觸發(fā)事件,參數(shù)為事件名;
- **off()??*用來解綁事件,參數(shù)為事件名;
- **all:**all有clear屬性,直接調(diào)用clear()屬性可以解綁全部事件。
以下代碼為展示emitter的基本用法:
//綁定事件test1,當(dāng)事件觸發(fā)時執(zhí)行回調(diào)
emitter.on('test1',()=>{
console.log('test1被調(diào)用了')
})
//綁定事件test2,當(dāng)事件觸發(fā)時執(zhí)行回調(diào)
emitter.on('test2',()=>{
console.log('test2被調(diào)用了')
})
//綁定事件test3,當(dāng)事件觸發(fā)時執(zhí)行回調(diào)
emitter.on('test3',()=>{
console.log('test3被調(diào)用了')
})
//觸發(fā)事件,每間隔1秒觸發(fā)一次
setInterval(()=>{
//觸發(fā)事件test1
emitter.emit('test1')
//觸發(fā)事件test2
emitter.emit('test2')
//觸發(fā)事件test3
emitter.emit('test3')
},1000)
//解綁事件,2秒后解綁test1
setTimeout(()=>{
emitter.off('test1')
console.log('--------test1解綁了')
},2000)
//解綁事件,4秒后解綁所有事件
setTimeout(()=>{
emitter.all.clear()
console.log('--------所有的事件解綁了')
},4000)運(yùn)行后在控制臺輸出如下內(nèi)容:

emitter在組件中的用法
首先創(chuàng)建一個父組件,兩個子組件,父組件代碼如下:
<template>
<div class="father">
<h3>父組件</h3>
<Child1/>
<Child2/>
</div>
</template>
<script setup lang="ts" name="Father">
import Child1 from './Child1.vue'
import Child2 from './Child2.vue'
</script>
<style scoped>
.father{
margin: 5px;
background-color:rgb(79, 186, 111);
padding: 20px;
color: white;
}
</style>子組件1代碼:
<template>
<div class="child1">
<h3>子組件1</h3>
</div>
</template>
<script setup lang="ts" name="Child1">
</script>
<style scoped>
.child1{
margin: 5px;
background-color: rgba(7, 7, 7, 0.224);
border: 1px solid;
border-color: white;
box-shadow: 0 0 5px;
padding: 10px;
color: #760e0e;
}
</style>子組件2代碼:
<template>
<div class="child2">
<h3>子組件2</h3>
</div>
</template>
<script setup lang="ts" name="Child2">
</script>
<style scoped>
.child2{
margin: 5px;
background-color: rgba(255, 255, 255, 0.224);
border: 1px solid;
border-color: white;
box-shadow: 0 0 5px;
padding: 10px;
color: #05035f;
}
</style>運(yùn)行效果如下:

然后我們在子組件1中準(zhǔn)備一些數(shù)據(jù)如下:
//數(shù)據(jù)
let book = reactive({
name:'西游記',
author:'吳承恩',
price:119.95
})然后在頁面中展示:
<!-- 展示 -->
<h4>圖書名稱:{{ book.name }}</h4>
<h4>圖書作者:{{ book.author }}</h4>
<h4>圖書價格:¥{{ book.price }}</h4>運(yùn)行效果如下:

接下來在子組件2中引入emitter,然后創(chuàng)建book數(shù)據(jù),給emitter綁定事件,并傳入回調(diào)函數(shù):
//引入emitter
import emitter from '@/utils/emitter';
import { reactive } from 'vue';
//數(shù)據(jù)
let book = reactive({
name:'',
author:'',
price:null
})
//給emitter綁定getBook事件,傳入回調(diào)函數(shù),回調(diào)函數(shù)接收一個參數(shù)
emitter.on('getBook',(value:any)=>{
// console.log(value)
book.name = value.name
book.author = value.author
book.price = value.price
})然后在子組件1中創(chuàng)建一個按鈕,綁定click事件,觸發(fā)getBook事件,并傳遞book參數(shù):
<button @click="emitter.emit('getBook',book)">將book信息發(fā)送給子組件2</button>最后在子組件2中展示接收的到的信息:
<!-- 展示 -->
<h4>圖書名稱:{{ book.name }}</h4>
<h4>圖書作者:{{ book.author }}</h4>
<h4>圖書價格:¥{{ book.price }}</h4>最后運(yùn)行后頁面效果如下:

點(diǎn)擊按鈕后效果如下:

至此已經(jīng)完成了子組件1向子組件2通信。
子組件1完整代碼如下:
<template>
<div class="child1">
<h3>子組件1</h3>
<!-- 展示 -->
<h4>圖書名稱:{{ book.name }}</h4>
<h4>圖書作者:{{ book.author }}</h4>
<h4>圖書價格:¥{{ book.price }}</h4>
<button @click="emitter.emit('getBook',book)">將book信息發(fā)送給子組件2</button>
</div>
</template>
<script setup lang="ts" name="Child1">
import emitter from '@/utils/emitter';
import { reactive } from 'vue';
//數(shù)據(jù)
let book = reactive({
name:'西游記',
author:'吳承恩',
price:119.95
})
</script>
<style scoped>
.child1{
margin: 5px;
background-color: rgba(7, 7, 7, 0.224);
border: 1px solid;
border-color: white;
box-shadow: 0 0 5px;
padding: 10px;
color: #760e0e;
}
</style>子組件2 的完整代碼如下:
<template>
<div class="child2">
<h3>子組件2</h3>
<!-- 展示 -->
<h4>圖書名稱:{{ book.name }}</h4>
<h4>圖書作者:{{ book.author }}</h4>
<h4>圖書價格:¥{{ book.price }}</h4>
</div>
</template>
<script setup lang="ts" name="Child2">
//引入emitter
import emitter from '@/utils/emitter';
import { reactive } from 'vue';
//數(shù)據(jù)
let book = reactive({
name:'',
author:'',
price:null
})
//給emitter綁定getBook事件,傳入回調(diào)函數(shù),回調(diào)函數(shù)接收一個參數(shù)
emitter.on('getBook',(value:any)=>{
// console.log(value)
book.name = value.name
book.author = value.author
book.price = value.price
})
</script>
<style scoped>
.child2{
margin: 5px;
background-color: rgba(255, 255, 255, 0.224);
border: 1px solid;
border-color: white;
box-shadow: 0 0 5px;
padding: 10px;
color: #05035f;
}
</style>總結(jié)
接收數(shù)據(jù)的組件必須要先綁定事件(訂閱),發(fā)送數(shù)據(jù)的組件要觸發(fā)事件,只要組件中引入了emitter,并執(zhí)行了emitter.emit()代碼并傳遞參數(shù),即可實(shí)現(xiàn)任意組件間的通信。
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
使用yarn?build?打包vue項(xiàng)目時靜態(tài)文件或圖片未打包成功的問題及解決方法
這篇文章主要介紹了使用yarn?build?打包vue項(xiàng)目時靜態(tài)文件或圖片未打包成功的問題及解決方法,解決方法不復(fù)雜通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-08-08
vue父組件向子組件(props)傳遞數(shù)據(jù)的方法
這篇文章主要介紹了vue父組件向子組件(props)傳遞數(shù)據(jù)的方法,文中給大家補(bǔ)充介紹了vue父子組件間傳值(props)的實(shí)現(xiàn)代碼,需要的朋友可以參考下2018-01-01
Vue手把手教你擼一個 beforeEnter 鉤子函數(shù)
這篇文章主要介紹了Vue手把手教你擼一個 beforeEnter 鉤子函數(shù),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-04-04
vue3使用defineModel實(shí)現(xiàn)父子組件雙向綁定
這篇文章主要個給大家介紹了在vue3中使用defineModel進(jìn)行父子組件中的雙向綁定,文中通過代碼示例給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-01-01
前端實(shí)現(xiàn)簡單的sse封裝方式(React hook Vue3)
這篇文章主要介紹了前端實(shí)現(xiàn)簡單的sse封裝方式(React hook Vue3),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08
Vue?element-ui中表格過長內(nèi)容隱藏顯示的實(shí)現(xiàn)方式
在Vue項(xiàng)目中,使用ElementUI渲染表格數(shù)據(jù)時,如果某一個列數(shù)值長度超過列寬,會默認(rèn)換行,造成顯示不友好,下面這篇文章主要給大家介紹了關(guān)于Vue?element-ui中表格過長內(nèi)容隱藏顯示的實(shí)現(xiàn)方式,需要的朋友可以參考下2022-09-09

