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

Vue3組件通信的方法大全

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

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

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

1. Props (父 -> 子)

  • 一句話解釋:父親(父組件)遞給兒子(子組件)一本《家規(guī)》(數(shù)據(jù)),兒子必須遵守。
  • 幽默比喻:這就是“龍生龍,鳳生鳳,老鼠的兒子會打洞”。父親有什么“遺傳基因”(數(shù)據(jù)),就通過props傳給兒子。兒子可以“看”和“用”這本家規(guī),但不能直接修改,否則就是“大逆不道”(單向數(shù)據(jù)流原則)。
  • 使用方法
  • 父組件 (Parent.vue):通過屬性綁定的方式傳值。
<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>
// 接收父組件傳來的props
const props = defineProps({
  name: String,
  age: {
    type: Number,
    required: true,
    default: 10
  }
});
</script>

2. Emits (子 -> 父)

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

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

<template>
  <button @click="tellDad">告訴爸爸我長大了</button>
</template>

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

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

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

<template>
  <ChildComponent @grow-up="handleChildGrowUp" />
  <p>來自兒子的消息:{{ 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 (雙向綁定語法糖)

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

子組件 (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 (父 -> 子)

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

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

<template>
  <p>我是一個深藏不露的組件</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() {
  // 通過.value訪問到子組件實例,并調(diào)用其暴露的方法
  childRef.value.doPushUp();
}
</script>

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

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

5. Provide / Inject

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

祖先組件 (GrandParent.vue)

<template>
  <ParentComponent />
</template>

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

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

后代組件 (GrandChild.vue)

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

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

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

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

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

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

  • 一句話解釋:建立一個“全局中央銀行”(Store),所有組件都可以來這里存錢(修改state)、取錢(讀取state)或辦理業(yè)務(wù)(調(diào)用actions)。
  • 幽默比喻:想象一下,整個應(yīng)用是一個城市,Pinia就是這個城市的中央銀行。無論你是住在城東的A組件,還是城西的B組件,大家共用一個銀行賬戶。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">歡迎回來, {{ 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)建一個全局的“廣播站”,一個組件可以向某個頻道廣播,另一個組件可以收聽這個頻道。
  • 幽默比喻:Vue2時代的EventBus就像一個公共的對講機頻道。任何人都可以拿起來喊話,也任何人都可以收聽。這在小型應(yīng)用里很方便,但在大型應(yīng)用里,你不知道是誰在喊話,也不知道誰在聽,容易造成混亂。Vue3官方移除了這個功能,但我們可以用mitt這樣的小庫來自己實現(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', '來自A組件的問候');
}
</script>

組件B (接收方)

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

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

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

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

訾博同學(xué),我們來畫個重點,做個總結(jié):

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

為師的忠告

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

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

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

Vue3通信口訣

父傳子,用 Props,兒子不能隨便改。
子傳父,靠 Emits,爹聽事件樂開懷。
雙向綁,v-model,省事方便真不賴。
爺孫傳,Provide,Inject 注入接過來。
兄弟情,狀態(tài)亂,Pinia 銀行管起來。
事件總線 Mitt 在,偶爾用用別依賴。
父控子,用 refexpose 暴露才存在。
牢記最佳實踐,代碼整潔人人愛!

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

相關(guān)文章

最新評論

平定县| 庆阳市| 贡觉县| 民乐县| 横峰县| 苗栗市| 秦安县| 白玉县| 龙门县| 隆化县| 无锡市| 耿马| 泰安市| 勃利县| 乐昌市| 八宿县| 会东县| 潍坊市| 娄烦县| 海林市| 瑞昌市| 泰宁县| 富裕县| 石城县| 贡山| 益阳市| 南昌县| 贵南县| 体育| 凌海市| 建湖县| 大理市| 赤峰市| 涿鹿县| 东乡县| 昭觉县| 北宁市| 蓬安县| 香港| 新疆| 东源县|