Vue3的組件通信方式

通信方式

適用層級

數據流向

復雜度

Props/Emits

父子組件

單向/雙向

★☆☆

v-model

父子組件

雙向

★☆☆

Provide/Inject

跨層級組件

自上而下

★★☆

事件總線

任意組件

任意方向

★★★

Pinia/Vuex

全局狀態

任意方向

★★☆

Refs模板引用

父子組件

父→子

★☆☆

作用域插槽

父子組件

子→父

★★☆

Web Workers

跨線程通信

任意方向

★★★★

1. Props/Emits:基礎父子通信

適用場景:直接父子組件通信
注意:避免直接修改props,使用emit通知父組件修改

<!-- 父組件 -->
<script?setup>
import?Child?from?'./Child.vue';
const?message = ref('父組件數據');
const?handleEmit =?(data) =>?{console.log('子組件傳遞:', data);
};
</script><template><Child?:msg="message"?@child-event="handleEmit"?/>
</template><!-- 子組件 Child.vue -->
<script?setup>
const?props = defineProps(['msg']);
const?emit = defineEmits(['child-event']);const?sendToParent =?()?=>?{emit('child-event', {?time:?new?Date() });
};
</script><template><div>收到: {{ msg }}</div><button?@click="sendToParent">發送事件</button>
</template>
2. v-model 雙向綁定升級

優勢:替代Vue2的.sync修飾符,語法更簡潔
原理:相當于?:modelValue?+?@update:modelValue

<!-- 父組件 -->
<script?setup>
import?CustomInput?from?'./CustomInput.vue';
const?username = ref('');
</script><template><CustomInput?v-model="username"?/>
</template><!-- 子組件 CustomInput.vue -->
<script?setup>
const?model = defineModel();
</script><template><input?type="text":value="model"@input="model = $event.target.value"/>
</template>
3. Provide/Inject 跨層級通信

適用場景:多級嵌套組件共享數據
注意:避免濫用,復雜場景建議用狀態管理

// 祖先組件
<script setup>
import?{ provide, ref }?from?'vue';
const?theme = ref('dark');
provide('app-theme', {theme,toggle:?()?=>?{theme.value = theme.value ===?'dark'???'light'?:?'dark';}
});
</script>// 任意后代組件
<script setup>
import { inject } from 'vue';
const { theme, toggle } = inject('app-theme');
</script><template><button?@click="toggle">當前主題: {{ theme }}</button>
</template>
4. 事件總線替代方案(mitt)

適用場景:非父子組件通信
優勢:輕量級(僅200B),替代Vue2的$emit/$on

// eventBus.js
import?mitt?from?'mitt';
export?default?mitt();// 組件A(發布事件)
import?bus?from?'./eventBus';
bus.emit('user-login', {?user:?'admin'?});// 組件B(訂閱事件)
import?bus?from?'./eventBus';
bus.on('user-login', (userData) => {console.log('用戶登錄:', userData);
});// 組件卸載時取消訂閱
onUnmounted(()?=>?{bus.off('user-login');
});
5. pinia狀態管理(推薦)

優勢:類型安全、Devtools支持、模塊化設計
對比Vuex:更簡潔API,去除mutations概念

// stores/user.js
import?{ defineStore }?from?'pinia';
export?const?useUserStore = defineStore('user', {state:?()?=>?({?name:?'',?isLogin:?false?}),actions: {login(name) {this.name = name;this.isLogin =?true;}}
});// 組件中使用
<script?setup>
import?{ useUserStore }?from?'@/stores/user';
const?userStore = useUserStore();const?login =?()?=>?{userStore.login('張三');
};
</script><template><div>用戶名: {{ userStore.name }}</div>
</template>
6. 模板引用通信

適用場景:父組件需要直接訪問子組件方法或數據
限制:只能在父子組件間使用

<!-- 父組件 -->
<script?setup>
import?Child?from?'./Child.vue';
import?{ ref, onMounted }?from?'vue';const?childRef = ref(null);onMounted(()?=>?{// 調用子組件方法childRef.value?.childMethod();// 訪問子組件數據console.log(childRef.value?.childData);
});
</script><template><Child?ref="childRef"?/>
</template><!-- 子組件 Child.vue -->
<script?setup>
import?{ defineExpose }?from?'vue';const?childData = ref('子組件數據');
const?childMethod =?()?=>?{console.log('子組件方法被調用');
};// 暴露給父組件
defineExpose({childData,childMethod
});
</script>
7. 作用域插槽(子→父通信)

適用場景:子組件需要向父組件傳遞渲染內容
優勢:保持子組件封裝性的同時提供定制能力

<!-- 子組件 ScopedList.vue -->
<script?setup>
const?items = ref(['Vue',?'React',?'Angular']);
</script><template><ul><li?v-for="(item, index) in items"?:key="index"><slot?:item="item"?:index="index"?/></li></ul>
</template><!-- 父組件 -->
<script?setup>
import?ScopedList?from?'./ScopedList.vue';
</script><template><ScopedList?v-slot="{ item, index }"><span?:class="{ active: index === 0 }">{{ item }}</span></ScopedList>
</template>
8. Web Workers 跨線程通信

適用場景:CPU密集型任務,避免阻塞UI線程
注意:worker中無法訪問DOM

// worker.js
self.onmessage =?(e) =>?{const?result = heavyCalculation(e.data);self.postMessage(result);
};function?heavyCalculation(data)?{// 復雜計算邏輯return?data *?2;
}// 組件中使用
<script setup>
import?{ ref }?from?'vue';const?worker =?new?Worker('./worker.js');
const?result = ref(0);worker.onmessage =?(e) =>?{result.value = e.data;
};const?startCalc =?()?=>?{worker.postMessage(1000000);?// 發送大數據
};
</script><template><button @click="startCalc">開始計算</button><div>結果: {{ result }}</div>
</template>

通信方式對比指南

通信方式

適用場景

優點

缺點

Props/Emits

父子組件簡單通信

簡單直接

多層傳遞繁瑣

v-model

表單組件雙向綁定

語法簡潔

僅適用特定場景

Provide/Inject

跨層級組件共享

避免逐層傳遞

數據來源不透明

事件總線

任意組件間事件通知

靈活解耦

難以跟蹤調試

Pinia/Vuex

全局狀態管理

集中管理,調試友好

學習成本較高

模板引用

父組件訪問子組件內部

精確訪問

破壞組件封裝性

作用域插槽

子組件向父組件暴露渲染數據

靈活定制UI

僅適用于模板內容

Web Workers

后臺計算任務

避免UI阻塞

通信成本高

實戰選型建議

  1. 父子組件:優先使用?props/emits?+?v-model

  2. 兄弟組件:采用共享父組件狀態 或?事件總線

  3. 祖孫組件:使用?provide/inject

  4. 復雜應用Pinia?管理全局狀態

  5. 性能敏感Web Workers?處理計算密集型任務

  6. UI定制作用域插槽?實現內容分發

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

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

相關文章

創客匠人:大健康創始人IP如何用“社會責任”構建品牌護城河

一、商業與責任的失衡困局部分大健康IP將利潤置于首位&#xff0c;甚至犧牲用戶利益&#xff0c;導致品牌形象脆弱。某保健品公司因夸大宣傳被曝光后&#xff0c;盡管銷量曾達千萬&#xff0c;卻因缺乏社會認同&#xff0c;一夜之間崩塌&#xff0c;證明沒有社會責任支撐的商業…

AI:機器人未來的形態是什么?

機器人未來的形態將受到技術進步、應用場景需求和社會接受度的綜合影響&#xff0c;以下是對未來機器人形態的預測&#xff0c;涵蓋技術趨勢、設計方向和應用場景&#xff1a; 1. 形態多樣化與通用化 人形機器人&#xff08;Humanoid Robots&#xff09;&#xff1a; 趨勢&…

創建 UIKit 項目教程

一、打開 XCode&#xff0c;選擇 iOS 下的 App&#xff0c;然后點 Next二、Interface 選擇 Storyboard&#xff0c;然后點 Next三、刪掉 Main.storyboard四、刪掉 SceneDelegate.swift五、AppDelegate.swift 只保留第一個函數六、在 AppDelegate.swift 文件里的 application 函…

防爬蟲君子協定 Robots.txt 文件

1.什么是robots.txt ? robots.txt是一個位于網站根目錄的文本文件,用于指導搜索引擎爬蟲如何訪問和抓取網站內容。它遵循特定的語法規則,是網站與爬蟲通信的重要工具。當搜索引擎訪問一個網站時,它首先會檢查該網站的根域下是否有一個叫做robots.txt的純文本文件。Robots.…

淺談 Python 中的 yield——生成器對象與函數調用的區別

我們來看這么一個例子&#xff1a; def greeter():name yield "你是誰&#xff1f;"yield f"你好&#xff0c;{name}"g greeter() print(next(g)) # → "你是誰&#xff1f;" print(g.send("張三")) # → "你好&#xf…

云端docker小知識

1、docker的三個關鍵概念image、container、dockerfile2、docker的container3、dockerfile4、docker制作image5、linux&#xff08;ubuntu&#xff09;安裝docker&#xff08;步驟1和4&#xff09;6、docker基本命令docker images 查看全部鏡像docker rmi -f 1e5f3c5b981a 刪除…

【Elasticsearch】昂貴算法與廉價算法

在 Elasticsearch 里&#xff0c;“昂貴”并不單指“CPU 時間”&#xff0c;而是綜合了 **CPU、內存、磁盤 I/O、網絡傳輸** 以及 **實現復雜度** 的代價。下面把常見“昂貴算法”拆開說&#xff1a;1. **高計算密度的文本算法** ? **match_phrase slop**&#xff08;帶跨距…

深度學習-多分類

?開頭摘要??&#xff1a; 本文將深入探討如何使用PyTorch實現基于Softmax回歸的MNIST手寫數字識別系統。從多分類問題的核心概念出發&#xff0c;詳細解析??One-Hot編碼??技術如何將類別標簽向量化&#xff0c;剖析??交叉熵損失函數??的數學原理及其在訓練中的優化機…

JVM 類加載過程

一、加載&#xff08;Loading&#xff09;目標&#xff1a;把字節碼文件&#xff08;.class&#xff09;“讀入 JVM”&#xff0c;生成類的 “半成品”&#xff08;Class 對象&#xff09;。Bootstrap ClassLoader&#xff08;啟動類加載器&#xff09;&#xff1a;負責加載 JV…

通俗范疇論13 雞與蛋的故事番外篇

通俗范疇論13 雞與蛋的故事番外篇 在上一篇中,我們得到了雞與蛋的Set局部小范疇如下: 雞與蛋 SetSetSet 局部小范疇 如上圖所示,每個雞來自于一個蛋,每個蛋來自于一只雞,如此循環,以至于無窮… 是的,假設雞與蛋兩個對象代表的集合,都是無窮集合,這個系統就沒有問題…

記錄跟隨recyclerview滑動的指示器

老早之前做的一個功能&#xff0c;橫向recyclerview滑動時&#xff0c;底部做跟隨滑動指示器。今天代碼不用了&#xff0c;記錄下代碼。<LinearLayoutandroid:layout_width"match_parent"android:layout_height"wrap_content"android:layout_marginTop&…

快速過一遍Python基礎語法

前言 本文章是深度學習的前導課&#xff0c;對有編程基礎的小伙伴更加的友好&#xff08;C、C&#xff09;&#xff0c;如果完全沒有學過任何一門編程語言也沒有關系&#xff0c;本文章不會涉及到晦澀難懂的原理&#xff0c;只是簡單的帶大家過一遍Python的基礎語法。 下面的操…

[爬蟲實戰] 多進程/多線程/協程-異步爬取豆瓣Top250

相關爬蟲知識點&#xff1a;[爬蟲知識] 深入理解多進程/多線程/協程的異步邏輯 相關爬蟲專欄&#xff1a;JS逆向爬蟲實戰 爬蟲知識點合集 爬蟲實戰案例 逆向知識點合集 前言&#xff1a; 在之前文章中&#xff0c;我們深入探討了多進程、多線程和協程這三大異步技術的工作…

Git系列--1.初始Git

一、背景 目錄 一、背景 二、認識 三、如何在Linux上安裝Git 3.1檢測git是否存在和版本 3.2安裝和卸載git 3.2.1Centos 3.2.2Ubuntu 四、基本操作 4.1創建本地倉庫 4.2必須的配置項 4.3宏觀認識基本分區 我們會根據需求不斷更改我們的文件內容&#xff0c;但有時我們會…

QWidget的屬性

QWidget的屬性 windowOpacityAPI說明windowOpacity()獲取不透明數值&#xff0c;返回float&#xff0c;取值為0.0到1.0&#xff0c;其中0.0為全透明&#xff0c;1.0為完全不透明setWindowOpacity()設置控件的不透明數值注意點&#xff1a;窗口不透明度的變化并非精確的&#xf…

【PTA數據結構 | C語言版】后綴表達式求值

本專欄持續輸出數據結構題目集&#xff0c;歡迎訂閱。 文章目錄題目代碼題目 請編寫程序&#xff0c;求給定的后綴表達式的值。 輸入格式&#xff1a; 輸入在一行中給出一個非空后綴表達式&#xff0c;其中操作數為 int 型整數&#xff0c;操作符包括加、減、乘、除、取模。各…

裝配式建筑4.0:當房子像汽車一樣被“智造”

傳統建筑方式&#xff0c;如同手工打造藝術品一般&#xff0c;大部分工作依賴現場施工&#xff0c;工人在建筑工地進行混凝土澆筑、磚塊堆砌、鋼筋綁扎等繁雜工作。這種方式受天氣、工人技術水平等因素影響極大&#xff0c;不僅施工周期漫長&#xff0c;質量也參差不齊。據統計…

Go語言生態成熟度分析:為何Go還無法像Java那樣實現注解式框架?

近年來&#xff0c;Go語言因其性能高效、部署簡單、并發模型優秀等特性&#xff0c;成為云原生與微服務架構中的熱門語言。然而&#xff0c;在實際的企業級項目開發中&#xff0c;開發者普遍會發現一個現象&#xff1a;Go的開發效率&#xff0c;尤其在快速構建中大型業務系統時…

oc分類和swift擴展有哪些區別

目錄1. 語言環境2. 主要目的3. 核心能力對比4. 關鍵差異詳解4.1. 屬性支持4.2. Swift 擴展4.3. 初始化器4.4. 方法沖突與覆蓋4.5. 關聯類型與泛型5. 設計哲學6. 總結表在 Objective-C 和 Swift 中&#xff0c;分類&#xff08;Category&#xff09;和擴展&#xff08;Extension…

go.work

一般學習一個小東西時&#xff0c;無非兩點&#xff0c;1、怎么用&#xff1f; 2、為啥用&#xff1f;在寫一個小的項目demo時&#xff0c;忽然看到一個奇怪的東西“go.work”&#xff1f;這是啥&#xff1f;好奇&#x1f62f;&#xff0c;想知道。我是這么問AI的&#xff1a;g…