【Vue】組件通信(Props/Emit、EventBus、Provide/Inject)

在這里插入圖片描述

個人主頁:Guiat
歸屬專欄:Vue

在這里插入圖片描述

文章目錄

  • 1. Props/Emit 父子組件通信
    • 1.1 Props 向下傳遞數據
    • 1.2 Emit 向上傳遞事件
  • 2. EventBus 跨組件通信
    • 2.1 創建事件總線
    • 2.2 使用事件總線
    • 2.3 EventBus 優缺點
  • 3. Provide/Inject 深層組件通信
    • 3.1 基本使用
    • 3.2 響應式處理
    • 3.3 Provide/Inject 優缺點
  • 4. 各通信方式對比與選擇
  • 5. 最佳實踐建議

正文

1. Props/Emit 父子組件通信

1.1 Props 向下傳遞數據

Props 是 Vue 中最基本的組件通信方式,用于父組件向子組件傳遞數據。

// 子組件定義
export default {name: 'ChildComponent',props: {// 基礎類型檢查message: String,// 多種類型propA: [String, Number],// 必填項requiredProp: {type: String,required: true},// 帶默認值propWithDefault: {type: Number,default: 100},// 對象/數組默認值objectProp: {type: Object,default: () => ({ key: 'value' })},// 自定義驗證customProp: {validator(value) {return ['success', 'warning', 'danger'].includes(value)}}}
}

1.2 Emit 向上傳遞事件

子組件通過觸發事件向父組件傳遞信息。

// 子組件
<template><div><button @click="sendToParent">發送到父組件</button></div>
</template><script>
export default {emits: ['update', 'delete'], // 聲明組件發出的事件methods: {sendToParent() {// 觸發事件并傳遞數據this.$emit('update', { id: 1, name: '更新的數據' })}}
}
</script>
// 父組件
<template><child-component @update="handleUpdate"@delete="handleDelete"/>
</template><script>
export default {methods: {handleUpdate(data) {console.log('收到子組件數據:', data)},handleDelete(id) {console.log('刪除ID:', id)}}
}
</script>

2. EventBus 跨組件通信

2.1 創建事件總線

EventBus 允許任意組件間通信,不受組件層級限制。

// Vue 2 創建事件總線
// eventBus.js
import Vue from 'vue'
export const EventBus = new Vue()// Vue 3 創建事件總線
// eventBus.js
import mitt from 'mitt'
export const EventBus = mitt()

2.2 使用事件總線

// 組件A - 發送事件
import { EventBus } from '@/eventBus'export default {methods: {sendMessage() {// Vue 2EventBus.$emit('custom-event', { message: '這是一條消息' })// Vue 3EventBus.emit('custom-event', { message: '這是一條消息' })}}
}
// 組件B - 接收事件
import { EventBus } from '@/eventBus'export default {created() {// Vue 2EventBus.$on('custom-event', this.handleEvent)// Vue 3EventBus.on('custom-event', this.handleEvent)},beforeDestroy() { // Vue 2EventBus.$off('custom-event', this.handleEvent)},beforeUnmount() { // Vue 3EventBus.off('custom-event', this.handleEvent)},methods: {handleEvent(data) {console.log('收到事件數據:', data)}}
}

2.3 EventBus 優缺點

優點:

  • 使用簡單,可實現任意組件間通信
  • 不需要組件間有直接的引用關系

缺點:

  • 可能導致事件混亂,難以追蹤數據流向
  • 組件耦合度增加,不利于維護
  • 大型應用中建議使用Vuex/Pinia等狀態管理方案

3. Provide/Inject 深層組件通信

3.1 基本使用

適用于深層嵌套組件間通信,祖先組件提供數據,后代組件注入使用。

// 祖先組件提供數據
export default {provide() {return {// 提供靜態值theme: 'dark',// 提供響應式數據user: this.user,// 提供方法updateUser: this.updateUser}},data() {return {user: { name: '張三', role: 'admin' }}},methods: {updateUser(newUser) {this.user = newUser}}
}
// 后代組件注入數據
export default {inject: ['theme', 'user', 'updateUser'],// 或者使用別名和默認值inject: {appTheme: {from: 'theme',default: 'light'},currentUser: 'user'},methods: {changeUserRole() {this.updateUser({...this.currentUser, role: 'editor'})}}
}

3.2 響應式處理

Vue 3中使用provide/inject實現響應式通信:

// 祖先組件 (Vue 3)
import { provide, ref, readonly } from 'vue'export default {setup() {const count = ref(0)function increment() {count.value++}// 提供只讀值防止子組件修改provide('count', readonly(count))provide('increment', increment)return { count, increment }}
}
// 后代組件 (Vue 3)
import { inject } from 'vue'export default {setup() {const count = inject('count')const increment = inject('increment')return { count, increment }}
}

3.3 Provide/Inject 優缺點

優點:

  • 解決深層嵌套組件通信問題
  • 避免了"prop drilling"(屬性透傳)
  • Vue 3中與組合式API結合使用更加靈活

缺點:

  • 增加了組件間的隱式依賴
  • 重構時可能導致問題
  • 數據來源不明確,可能影響代碼可維護性

4. 各通信方式對比與選擇

通信方式適用場景優點缺點
Props/Emit父子組件通信簡單直接,Vue官方推薦層級深時需要多層傳遞
EventBus任意組件間通信使用簡單,無需組件關系事件難以追蹤,大型應用不推薦
Provide/Inject深層組件通信避免屬性透傳增加隱式依賴
Vuex/Pinia復雜應用狀態管理集中管理狀態,狀態變化可追蹤小型應用可能過于復雜
a t t r s / attrs/ attrs/listeners透傳屬性和事件無需顯式聲明即可傳遞僅適用于中間層組件傳遞

5. 最佳實踐建議

  1. 就近原則:優先使用最簡單的通信方式解決問題
  2. 明確數據流:保持單向數據流,便于追蹤和調試
  3. 合理拆分組件:減少不必要的組件嵌套和通信
  4. 狀態提升:將共享狀態提升到最近的共同父組件
  5. 大型應用:考慮使用Vuex/Pinia進行狀態管理
  6. 文檔化:為組件間的通信方式編寫清晰的文檔

通過合理選擇和組合這些通信方式,可以構建出數據流清晰、易于維護的Vue應用。

結語
感謝您的閱讀!期待您的一鍵三連!歡迎指正!

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/76528.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/76528.shtml
英文地址,請注明出處:http://en.pswp.cn/web/76528.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vulnhub sunset系列靶機合集(部分)

描述&#xff1a;該合集包含sunset系列適合新手的四個靶機&#xff08;sunset:1、dusk、sunrise、noontide&#xff09;的滲透全過程。 靶機下載地址&#xff1a;Vulnerable By Design - Search: sunset ~ VulnHubhttps://www.vulnhub.com/?qsunset sunset:1 滲透過程 信息…

【MySQL】MySQL的基礎語法及其語句的介紹

1、基礎語法 mysql -h【主機名】 -u【用戶名】 -p //登錄MySQL exit或quit; //退出MySQL show database; //查看MySQL下的所有數據庫 use 【數據庫名】; //進入數據庫 show tables; //查看數據庫下的所有表名 *MySQL的啟動和關閉 &am…

2025-4-20-C++ 學習 數組(1)

數組 2025-4-20-C++ 學習 數組(1)P1428 小魚比可愛題目描述輸入格式輸出格式輸入輸出樣例 #1輸入 #1輸出 #1說明/提示題解代碼P1427 小魚的數字游戲題目描述輸入格式輸出格式輸入輸出樣例 #1輸入 #1輸出 #1說明/提示數據規模與約定題解代碼P5727 【深基5.例3】冰雹猜想題目描…

ESP-ADF外設子系統深度解析:esp_peripherals組件架構與核心設計(顯示輸出類外設之LCD)

目錄 ESP-ADF外設子系統深度解析&#xff1a;esp_peripherals組件架構與核心設計&#xff08;顯示輸出類外設之LCD&#xff09;簡介模塊概述功能定義架構位置核心特性 LCD外設分析LCD外設概述LCD外設層次架構圖 LCD外設API和數據結構外設層API公共API內部數據結構 LCD外設配置選…

面試題:循環引用兩個節點相互引用,如何判斷哪個用 shared_ptr?哪個用 weak_ptr?

目錄 1.引言 2.原理 3.所有權模型與指針選擇 4.復雜場景的決策策略 5.注意事項 6.總結 1.引言 當兩個對象通過 shared_ptr 相互引用時&#xff0c;會產生循環引用問題&#xff0c;導致內存泄漏。因為這兩個對象的引用計數永遠不會變為 0&#xff0c;即使它們在程序的其他…

QT聊天項目DAY06

1.從git上同步項目 編譯測試&#xff0c;編譯通過 Post請求測試 測試成功 2. email is 打印有問題&#xff0c;檢查 解析結果是存儲在jsonResult中的&#xff0c;修改 3. 客戶端實現Post驗證碼請求 3.1 同步Qt客戶端項目 檢查QT版本&#xff0c;由于我在公司用的還是QT5.12.9…

PHP騰訊云人臉核身獲取FaceId

參考騰訊云官方文檔&#xff1a; 人臉核身 合作方后臺上傳身份信息_騰訊云 前提&#xff1a;已經獲取了SIGN Ticket。獲取參考文檔&#xff1a; PHP騰訊云人臉核身獲取SIGN Ticket-CSDN博客 public function getTxFaceId($uid,$name,$idNo){$appId ;$userId $uid;$nonce …

用 Deepseek 寫的uniapp油耗計算器

下面是一個基于 Uniapp 的油耗計算器實現&#xff0c;包含 Vue 組件和頁面代碼。 1. 創建頁面文件 在 pages 目錄下創建 fuel-calculator 頁面&#xff1a; <!-- pages/fuel-calculator/fuel-calculator.vue --> <template><view class"container"…

Redis ④-通用命令

Redis 是一個 客戶端-服務器 結構的程序&#xff0c;這與 MySQL 是類似的&#xff0c;這點需要牢記&#xff01;&#xff01;&#xff01; Redis 固然好&#xff0c;但也不是任何場景都適合使用 Redis&#xff0c;一定要根據當前的業務需求來選擇是否使用 Redis Redis 通用命令…

HarmonyOs學習 環境配置后 實驗1:創建項目Hello World

HarmonyOS開發入門&#xff1a;環境配置與Hello World實驗 實驗目標 掌握HarmonyOS開發環境配置&#xff0c;創建首個HarmonyOS應用并實現"Hello World"界面展示 實驗準備 已安裝DevEco Studio開發環境已配置HarmonyOS開發依賴項熟悉基本TypeScript/ArkTS語法&am…

HTTP:十.cookie機制

Cookie概念及類型 HTTP cookie,簡稱cookie,又稱數碼存根、“網站/瀏覽+魔餅/魔片”等,是瀏覽網站時由網絡服務器創建并由網頁瀏覽器存放在用戶計算機或其他設備的小文本文件。Cookie使Web服務器能在用戶的設備存儲狀態信息(如添加到在線商店購物車中的商品)或跟蹤用戶…

記錄小程序第一次調用Api,基于騰訊云Serverless函數,實現小程序的成功接入api,以及數據調用

目錄 創建騰訊云個人賬戶新建severless應用建立函數URL小程序中調用api示例 創建騰訊云個人賬戶 百度搜索即可&#xff0c;并注冊 新建severless應用 作者以github下載的某Api為例&#xff0c;這里不展示具體Api&#xff0c;只關注操作即可&#xff0c;相信都是互通的 在騰…

ES6 第一講 變量定義 堆與棧 字符串的擴展和數值型的擴展

文章目錄 1.ES6變量定義2.ES6堆和棧3.字符串的擴展3.1 模板字符串3.2 判斷是否以指定的字符串開頭或結尾3.3 字符串重復輸出3.4 填充方法3.5 去除前后字符串空格3.6 返回參數指定位置的字符 4. 數值型的擴展4.1 二進制0B 八進制0O4.2 判斷是否是一個無窮大的數字 &#xff08;判…

LeetCode第158題_用Read4讀取N個字符 II

LeetCode 第158題&#xff1a;用Read4讀取N個字符 II 題目描述 給你一個文件&#xff0c;并且該文件只能通過給定的 read4 方法來讀取&#xff0c;請實現一個方法來讀取 n 個字符。 read4 方法&#xff1a; API read4 可以從文件中讀取 4 個連續的字符&#xff0c;并且將它…

算法篇之單調棧

單調棧算法入門 單調棧是一種特殊的數據結構應用&#xff0c;它的核心在于維護一個棧&#xff0c;使得棧內元素保持單調遞增或者單調遞減的順序。這種數據結構在解決很多算法問題時非常有效&#xff0c;例如求數組中每個元素的下一個更大元素、每日溫度問題等。 一、單調棧的…

Kubernetes控制平面組件:調度器Scheduler(二)

云原生學習路線導航頁&#xff08;持續更新中&#xff09; kubernetes學習系列快捷鏈接 Kubernetes架構原則和對象設計&#xff08;一&#xff09;Kubernetes架構原則和對象設計&#xff08;二&#xff09;Kubernetes架構原則和對象設計&#xff08;三&#xff09;Kubernetes控…

【網絡】數據鏈路層知識梳理

全是通俗易懂的講解&#xff0c;如果你本節之前的知識都掌握清楚&#xff0c;那就速速來看我的筆記吧~ 自己寫自己的八股&#xff01;讓未來的自己看懂&#xff01; &#xff08;全文手敲&#xff0c;受益良多&#xff09; 數據鏈路層 我們來重新理解一下這個圖&#xff1a;…

機器學習(神經網絡基礎篇)——個人理解篇6(概念+代碼)

1 在聲明一個類中&#xff0c;構建一個屬于類的函數&#xff0c;前面為什要加上“self”&#xff1f; 就像下面這一串代碼&#xff1a; class TwoLayerNet:def __init__(self, input_size, hidden_size, output_size,weight_init_std0.01):# 初始化權重self.params {}self.p…

Cribl 對Windows-xml log 進行 -Removing filed-06

Removing Fields Description? The Eval Function can be used to add or remove fields. In this example we will remove the extracted fields while preserving _raw, _time,index,source, sourcetype. Steps - Adding an Eval Function

chili3d調試6 添加左側面板

注釋前 一個一個注釋看對應哪個窗口 無事發生 子方法不是顯示的窗口 注釋掉看看 沒了 注釋這個看看 零件頁面沒了 這個瀏覽器居然完全不用關的&#xff0c;刷新就重載了 注釋看看 無工具欄版本 sidebar&#xff1a; 往框框里面加入 div({ className: style.input }, user_…