最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue3組件通信的方法大全

 更新時(shí)間:2025年09月26日 08:59:20   作者:訾博ZiBo  
在Vue3中,組件通信仍然是一個(gè)非常重要的話題,因?yàn)樵诖蠖鄶?shù)應(yīng)用程序中,不同的組件之間需要進(jìn)行數(shù)據(jù)傳遞和交互,本文給大家介紹了Vue3組件通信的方法大全,需要的朋友可以參考下

一、 父子通信:最親密、最常見(jiàn)的“家庭內(nèi)部對(duì)話”

這是最基礎(chǔ)也是最重要的通信方式,就像父母和孩子之間的日常交流。

1. Props (父 -> 子)

  • 一句話解釋:父親(父組件)遞給兒子(子組件)一本《家規(guī)》(數(shù)據(jù)),兒子必須遵守。
  • 幽默比喻:這就是“龍生龍,鳳生鳳,老鼠的兒子會(huì)打洞”。父親有什么“遺傳基因”(數(shù)據(jù)),就通過(guò)props傳給兒子。兒子可以“看”和“用”這本家規(guī),但不能直接修改,否則就是“大逆不道”(單向數(shù)據(jù)流原則)。
  • 使用方法
  • 父組件 (Parent.vue):通過(guò)屬性綁定的方式傳值。
<template>
  <ChildComponent name="訾博" :age="18" />
</template>

<script setup>
import ChildComponent from './ChildComponent.vue';
</script>
  • 子組件 (ChildComponent.vue):使用defineProps接收。
<template>
  <p>大家好,我叫{{ name }},今年{{ age }}歲。</p>
</template>

<script setup>
// 接收父組件傳來(lái)的props
const props = defineProps({
  name: String,
  age: {
    type: Number,
    required: true,
    default: 10
  }
});
</script>

2. Emits (子 -> 父)

  • 一句話解釋:兒子(子組件)有事要向父親(父組件)匯報(bào),就大喊一聲(觸發(fā)事件)。
  • 幽默比喻:兒子在自己房間里考試得了100分,他不能直接沖到父親的賬本上把自己的零花錢改了。他得跑到客廳大喊:“爸!我考了100分!”($emit('got-full-marks', 100))。父親聽(tīng)到了,自然會(huì)決定給他加多少零花錢(在父組件的事件監(jiān)聽(tīng)函數(shù)里處理)。
  • 使用方法

子組件 (ChildComponent.vue):使用defineEmits聲明事件,然后通過(guò)emit函數(shù)觸發(fā)。

<template>
  <button @click="tellDad">告訴爸爸我長(zhǎng)大了</button>
</template>

<script setup>
// 聲明要觸發(fā)的事件
const emit = defineEmits(['grow-up']);

function tellDad() {
  // 觸發(fā)事件,并可以傳遞參數(shù)
  emit('grow-up', '我已經(jīng)會(huì)自己寫代碼了!');
}
</script>

父組件 (Parent.vue):在子組件標(biāo)簽上使用@v-on監(jiān)聽(tīng)事件。

<template>
  <ChildComponent @grow-up="handleChildGrowUp" />
  <p>來(lái)自兒子的消息:{{ messageFromChild }}</p>
</template>

<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';

const messageFromChild = ref('');

function handleChildGrowUp(message) {
  messageFromChild.value = message;
}
</script>

3. v-model (雙向綁定語(yǔ)法糖)

  • 一句話解釋propsemits的組合套餐,專門用于父子組件間的數(shù)據(jù)同步。
  • 幽默比喻:這就像一個(gè)對(duì)講機(jī)。父親可以通過(guò)對(duì)講機(jī)向兒子發(fā)號(hào)施令(props),兒子也能通過(guò)同一個(gè)對(duì)講機(jī)回應(yīng)情況(emits),兩邊信息實(shí)時(shí)同步。
  • 使用方法:Vue3的v-model更靈活,可以有多個(gè)。

子組件 (CustomInput.vue)

<template>
  <input :value="modelValue" @input="emit('update:modelValue', $event.target.value)" />
</template>

<script setup>
defineProps(['modelValue']);
const emit = defineEmits(['update:modelValue']);
</script>

父組件 (Parent.vue)

<template>
  <CustomInput v-model="searchText" />
  <p>你在搜索:{{ searchText }}</p>
</template>

<script setup>
import { ref } from 'vue';
import CustomInput from './CustomInput.vue';

const searchText = ref('');
</script>

4. ref / $refs (父 -> 子)

  • 一句話解釋:父親直接拿到兒子的“遙控器”,可以命令兒子做某些具體動(dòng)作(調(diào)用方法、訪問(wèn)屬性)。
  • 幽默比喻:這有點(diǎn)“霸道總裁”,不通過(guò)商量(事件),直接命令。比如父親想讓兒子現(xiàn)在立刻馬上去做個(gè)俯臥撐。這種方式不常用,因?yàn)樗茐牧私M件的封裝性,屬于“最后的手段”。
  • 使用方法

子組件 (ChildComponent.vue):使用defineExpose暴露方法或?qū)傩浴?/p>

<template>
  <p>我是一個(gè)深藏不露的組件</p>
</template>

<script setup>
import { ref } from 'vue';

const doPushUp = () => {
  console.log('正在做俯臥撐...');
};

// 把doPushUp方法暴露給父組件
defineExpose({
  doPushUp
});
</script>

父組件 (Parent.vue)

<template>
  <ChildComponent ref="childRef" />
  <button @click="commandChild">命令兒子</button>
</template>

<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';

const childRef = ref(null);

function commandChild() {
  // 通過(guò).value訪問(wèn)到子組件實(shí)例,并調(diào)用其暴露的方法
  childRef.value.doPushUp();
}
</script>

二、 跨代通信:當(dāng)“爺爺”想和“孫子”說(shuō)話

如果組件嵌套很深,一層一層地props下去,會(huì)累死人,這叫“Props Drilling”(屬性鉆探地獄)。為了避免這種情況,我們有更優(yōu)雅的方案。

5. Provide / Inject

  • 一句話解釋:祖先組件提供一個(gè)“共享寶藏”,任何后代組件都可以按“暗號(hào)”注入并使用它。
  • 幽默比喻:這就像你們訾家的祖?zhèn)髅胤?。老祖宗(祖先組件)通過(guò)provide把秘方藏在一個(gè)地方,并告訴后代“暗號(hào)”是什么。任何一個(gè)姓訾的子孫(后代組件),無(wú)論隔了多少代,只要報(bào)出暗號(hào)(inject),就能拿到這個(gè)秘方。外人(非后代組件)是拿不到的。
  • 使用方法

祖先組件 (GrandParent.vue)

<template>
  <ParentComponent />
</template>

<script setup>
import { provide, ref } from 'vue';

const themeColor = ref('dark');
// 提供數(shù)據(jù),'theme'是暗號(hào)
provide('theme', themeColor); 
</script>

后代組件 (GrandChild.vue)

<template>
  <div :style="{ color: theme }">我是孫子組件,我用的是祖?zhèn)髦黝}色。</div>
</template>

<script setup>
import { inject } from 'vue';

// 注入數(shù)據(jù),'theme'是暗號(hào)
const theme = inject('theme');
</script>

三、 任意組件通信:當(dāng)“隔壁老王”想找你聊天

對(duì)于兩個(gè)沒(méi)有任何親緣關(guān)系的組件,如何進(jìn)行交流?

6. Pinia (官方推薦的狀態(tài)管理庫(kù))

  • 一句話解釋:建立一個(gè)“全局中央銀行”(Store),所有組件都可以來(lái)這里存錢(修改state)、取錢(讀取state)或辦理業(yè)務(wù)(調(diào)用actions)。
  • 幽默比喻:想象一下,整個(gè)應(yīng)用是一個(gè)城市,Pinia就是這個(gè)城市的中央銀行。無(wú)論你是住在城東的A組件,還是城西的B組件,大家共用一個(gè)銀行賬戶。A組件往里存了100塊,B組件馬上就能查到余額變化。它規(guī)范、安全、可追溯(有DevTools),是管理復(fù)雜應(yīng)用狀態(tài)的“金標(biāo)準(zhǔn)”。
  • 使用方法

定義Store (/stores/user.js)

import { defineStore } from 'pinia';

export const useUserStore = defineStore('user', {
  state: () => ({
    name: '訾博',
    isLoggedIn: false,
  }),
  actions: {
    login() {
      this.isLoggedIn = true;
    },
  },
});

在任意組件中使用

<template>
  <p v-if="userStore.isLoggedIn">歡迎回來(lái), {{ userStore.name }}!</p>
  <button @click="userStore.login()">登錄</button>
</template>

<script setup>
import { useUserStore } from '@/stores/user';

const userStore = useUserStore();
</script>

7. Mitt / Tiny-emitter (全局事件總線)

  • 一句話解釋:創(chuàng)建一個(gè)全局的“廣播站”,一個(gè)組件可以向某個(gè)頻道廣播,另一個(gè)組件可以收聽(tīng)這個(gè)頻道。
  • 幽默比喻:Vue2時(shí)代的EventBus就像一個(gè)公共的對(duì)講機(jī)頻道。任何人都可以拿起來(lái)喊話,也任何人都可以收聽(tīng)。這在小型應(yīng)用里很方便,但在大型應(yīng)用里,你不知道是誰(shuí)在喊話,也不知道誰(shuí)在聽(tīng),容易造成混亂。Vue3官方移除了這個(gè)功能,但我們可以用mitt這樣的小庫(kù)來(lái)自己實(shí)現(xiàn)。
  • 使用方法

創(chuàng)建廣播站 (/utils/emitter.js)

import mitt from 'mitt';
const emitter = mitt();
export default emitter;

組件A (發(fā)送方)

<script setup>
import emitter from '@/utils/emitter';

function sendMessage() {
  emitter.emit('some-event', '來(lái)自A組件的問(wèn)候');
}
</script>

組件B (接收方)

<script setup>
import emitter from '@/utils/emitter';
import { onMounted, onUnmounted } from 'vue';

onMounted(() => {
  emitter.on('some-event', (message) => {
    console.log(message); // "來(lái)自A組件的問(wèn)候"
  });
});

// 記住,一定要在組件卸載時(shí)取消監(jiān)聽(tīng),否則會(huì)內(nèi)存泄漏!
onUnmounted(() => {
  emitter.off('some-event');
});
</script>

總結(jié)與老師的忠告

訾博同學(xué),我們來(lái)畫個(gè)重點(diǎn),做個(gè)總結(jié):

場(chǎng)景推薦方法核心思想推薦指數(shù)
父 -> 子Props單向數(shù)據(jù)流,清晰明了★★★★★
子 -> 父Emits事件觸發(fā),解耦★★★★★
父子雙向綁定v-modelprops和emits的語(yǔ)法糖★★★★★
跨代通信Provide / Inject依賴注入,避免屬性鉆探★★★★☆
復(fù)雜應(yīng)用/任意組件Pinia集中式狀態(tài)管理,可預(yù)測(cè)★★★★★
簡(jiǎn)單應(yīng)用/任意組件Mitt (事件總線)發(fā)布訂閱,簡(jiǎn)單靈活★★★☆☆
父組件調(diào)用子組件方法ref / defineExpose直接引用,應(yīng)急手段★★☆☆☆

為師的忠告

  1. 首選“家庭內(nèi)部”方案:優(yōu)先使用 PropsEmits。這是Vue設(shè)計(jì)的核心,能讓你的數(shù)據(jù)流向最清晰、最容易維護(hù)。
  2. 避免“屬性鉆探”:當(dāng) Props 需要傳遞超過(guò)兩層時(shí),就應(yīng)該立刻考慮使用 Provide / Inject
  3. 擁抱“中央銀行”:當(dāng)多個(gè)組件共享同一份狀態(tài)(比如用戶信息、主題設(shè)置),并且這個(gè)狀態(tài)會(huì)被多個(gè)組件修改時(shí),不要猶豫,直接上 Pinia。它能讓你的應(yīng)用狀態(tài)變得井井有條,而不是一團(tuán)亂麻。
  4. 慎用“大喇叭”和“遙控器”Mittref 都有其用武之地,但它們也更容易導(dǎo)致代碼難以追蹤和維護(hù)。把它們當(dāng)作你的“秘密武器”,非必要不使用。

專用于背誦的內(nèi)容

訾博,把下面這段口訣背下來(lái),面試和實(shí)戰(zhàn)中定能助你一臂之力!

Vue3通信口訣

父?jìng)髯?,?Props,兒子不能隨便改。
子傳父,靠 Emits,爹聽(tīng)事件樂(lè)開(kāi)懷。
雙向綁,v-model,省事方便真不賴。
爺孫傳,ProvideInject 注入接過(guò)來(lái)。
兄弟情,狀態(tài)亂,Pinia 銀行管起來(lái)。
事件總線 Mitt 在,偶爾用用別依賴。
父控子,用 ref,expose 暴露才存在。
牢記最佳實(shí)踐,代碼整潔人人愛(ài)!

以上就是Vue3組件通信的方法大全的詳細(xì)內(nèi)容,更多關(guān)于Vue3組件通信的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論

武陟县| 馆陶县| 渝北区| 双鸭山市| 甘肃省| 石家庄市| 屯门区| 贵州省| 巴楚县| 瓮安县| 柳州市| 宁波市| 宕昌县| 张家界市| 密云县| 濮阳市| 洛隆县| 鹿邑县| 武宣县| 伊通| 太和县| 从化市| 宜都市| 宜阳县| 玉山县| 新竹市| 夏河县| 措美县| 荔波县| 南部县| 衡山县| 永新县| 武义县| 任丘市| 新疆| 申扎县| 尚志市| 纳雍县| 衢州市| 金川县| 象山县|