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

Vue3中常見的組件傳參方式大全及對比詳解

 更新時間:2026年05月27日 09:39:13   作者:AI磚家  
本文詳細解析了Vue3中多種數(shù)據(jù)傳遞與通信方式,包括props/emits、v-model、provide/inject、ref、Pinia/Vex、組合式函數(shù)等,并對比了它們各自的優(yōu)缺點及適用場景,幫助開發(fā)者根據(jù)實際需求選擇最合適的方案,需要的朋友可以參考下

在 Vue3 的日常開發(fā)中,組件間的數(shù)據(jù)傳遞與通信是最基本的操作。面對不同的組件關系(父子、祖孫、兄弟、任意組件)和不同的交互需求(單向、雙向、共享狀態(tài)、跨層級透傳),Vue3 提供了豐富而靈活的傳參方案。本文將對 Vue3 中常見的傳參方式進行系統(tǒng)梳理,對比它們的特性和適用場景,幫助你根據(jù)實際情況做出最合適的選擇。

一、父子組件通信

1. Props —— 父傳子

父組件通過自定義屬性向子組件傳遞數(shù)據(jù),子組件用 defineProps 聲明接收。

<!-- 父組件 -->
<Child :title="pageTitle" :count="10" />
<!-- 子組件 -->
<script setup>
const props = defineProps({
  title: String,
  count: Number
})
</script>
<template>
  <h1>{{ props.title }}</h1>
</template>
  • 優(yōu)點:單向數(shù)據(jù)流,清晰可追蹤,是 Vue 官方推薦的基礎傳參方式。
  • 缺點:只能父傳子;當需要層層傳遞時,中間組件也會被迫接收無關屬性。
  • 場景:絕大部分父組件向直接子組件傳遞數(shù)據(jù)的場景。

2. Emits —— 子傳父

子組件通過 defineEmits 聲明事件,觸發(fā)時將數(shù)據(jù)作為參數(shù)回傳給父組件。

<!-- 子組件 -->
<script setup>
const emit = defineEmits(['update', 'delete'])
function handleClick() {
  emit('update', { id: 1, value: 'new' })
}
</script>
<!-- 父組件 -->
<Child @update="handleUpdate" />
  • 優(yōu)點:符合單向數(shù)據(jù)流,事件命名清晰,易于維護。
  • 缺點:只能子傳父,跨多級通信時代碼會變?nèi)唛L。
  • 場景:子組件通知父組件發(fā)生了某個行為,并傳遞附屬數(shù)據(jù)。

3. v-model —— 雙向綁定

Vue3 支持多個 v-model 綁定,本質是 prop + emit 的語法糖。子組件通過 defineProps 接收 modelValue,通過 defineEmits 觸發(fā) update:modelValue。

<!-- 父組件 -->
<CustomInput v-model="text" v-model:visible="show" />
<!-- 子組件 -->
<script setup>
const props = defineProps({
  modelValue: String,
  visible: Boolean
})
const emit = defineEmits(['update:modelValue', 'update:visible'])
function updateValue(e) {
  emit('update:modelValue', e.target.value)
}
</script>
  • 優(yōu)點:語義化的雙向綁定,簡潔高效;支持多個 v-model 和自定義修飾符。
  • 缺點:仍是父子通信的延伸,不適用于跨層級。
  • 場景:表單控件、彈窗顯隱、任何需要子組件即時同步數(shù)據(jù)到父組件的場景。

4. Ref +defineExpose—— 父組件直接訪問子組件

父組件通過 ref 獲取子組件實例,子組件通過 defineExpose 暴露方法和數(shù)據(jù)。

<!-- 父組件 -->
<script setup>
import { ref } from 'vue'
const childRef = ref(null)
function focusInput() {
  childRef.value?.focus()
}
</script>
<template>
  <Child ref="childRef" />
</template>
<!-- 子組件 -->
<script setup>
import { ref } from 'vue'
const inputRef = ref(null)
function focus() {
  inputRef.value?.focus()
}
defineExpose({ focus })
</script>
  • 優(yōu)點:父組件可以命令式地調用子組件方法,比事件更直接。
  • 缺點:破壞了組件封裝性,增加了耦合;只能用于父子之間。
  • 場景:需要父組件集中控制子組件行為(如調用子組件內(nèi)部方法、手動獲取表單值等),且沒有更優(yōu)雅的聲明式替代方案時。

二、祖孫 / 跨層級通信

5. provide / inject —— 依賴注入

祖先組件通過 provide 提供數(shù)據(jù),任意后代組件通過 inject 接收。

<!-- 祖先組件 -->
<script setup>
import { provide, ref } from 'vue'
const theme = ref('dark')
provide('theme', theme)
</script>
<!-- 后代組件 -->
<script setup>
import { inject } from 'vue'
const theme = inject('theme', 'light') // 可設默認值
</script>
  • 優(yōu)點:任意跨層級傳遞,無需中間組件參與;響應式數(shù)據(jù)依然保持響應。
  • 缺點:數(shù)據(jù)來源不夠直觀,依賴注入的 key 可能沖突;過度使用會導致組件間關系模糊。
  • 場景:全局主題、語言、用戶信息、表單禁用狀態(tài)等需要跨層級共享的數(shù)據(jù)。

6. 透傳 Attributes ($attrs)

父組件傳遞給子組件、但子組件未聲明為 props 的屬性,會被自動透傳到子組件的根元素上??赏ㄟ^ useAttrs() 獲取這些屬性。

<!-- 父組件 -->
<Child class="box" data-test="hello" />
<!-- 子組件 -->
<script setup>
import { useAttrs } from 'vue'
const attrs = useAttrs()
console.log(attrs.class) // 'box'
</script>
<template>
  <div v-bind="attrs">...</div>
</template>
  • 優(yōu)點:簡化了“中間組件轉發(fā)屬性”的模板代碼;適合構建二次封裝組件。
  • 缺點:只能傳遞屬性,不適合傳遞復雜邏輯數(shù)據(jù);多層透傳時調試困難。
  • 場景:封裝 UI 組件庫時,將未識別的屬性和事件自動傳遞給底層原生元素或組件。

三、全局狀態(tài)管理

7. Pinia(或 Vuex)

將共享狀態(tài)抽離到全局 Store 中,任意組件都可以直接讀寫。

// stores/counter.js
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  function increment() { count.value++ }
  return { count, increment }
})
<!-- 任意組件 -->
<script setup>
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore()
</script>
<template>
  <span>{{ counter.count }}</span>
  <button @click="counter.increment()">+</button>
</template>
  • 優(yōu)點:真正解耦,任意層級、任意關系的組件都能共享數(shù)據(jù)和邏輯;支持 DevTools 調試。
  • 缺點:引入了額外的庫和概念,簡單場景下可能過于繁重。
  • 場景:多個組件(特別是非父子關系的)需要共享同一份狀態(tài),如用戶登錄狀態(tài)、購物車數(shù)據(jù)、多步驟表單中間數(shù)據(jù)等。

8. 組合式函數(shù)(Composables)共享狀態(tài)

將響應式狀態(tài)和邏輯抽取到一個組合函數(shù)中,利用 Vue 的模塊單例特性實現(xiàn)共享。

// composables/useSharedCount.js
import { ref } from 'vue'
const count = ref(0) // 模塊作用域單例
export function useSharedCount() {
  function increment() { count.value++ }
  return { count, increment }
}
<!-- 任意組件 -->
<script setup>
import { useSharedCount } from '@/composables/useSharedCount'
const { count, increment } = useSharedCount()
</script>
  • 優(yōu)點:比 Pinia 更輕量,適合簡單共享狀態(tài);與組合式 API 天然契合。
  • 缺點:無 DevTools 支持,不方便持久化和中間件;狀態(tài)難以被手動清理;對服務端渲染需要額外處理。
  • 場景:簡單的跨組件共享,如某幾個鄰近組件的臨時狀態(tài)、無需嚴格管理的全局變量。

四、其他常見傳參方式

9. 事件總線(mitt / tiny-emitter)

Vue3 移除了 $on/$off,可引入第三方庫如 mitt 實現(xiàn)任意組件間的發(fā)布-訂閱通信。

  • 優(yōu)點:完全不關心組件層級,任意組件可觸發(fā)和監(jiān)聽事件。
  • 缺點:全局事件容易造成“事件爆炸”,難以追蹤數(shù)據(jù)流;不利于類型推導;組件銷毀時需要手動解綁。
  • 場景:極少組件間的松耦合通信,或遺留項目遷移時的過渡方案。新項目不推薦優(yōu)先使用。

10. 路由傳參 (Vue Router)

通過路由參數(shù)、查詢參數(shù)或狀態(tài)傳遞數(shù)據(jù)。

  • 優(yōu)點:可在 URL 上持久化部分狀態(tài),方便分享和收藏;頁面間解耦。
  • 缺點:僅適用于路由跳轉場景,參數(shù)大小受限。
  • 場景:頁面間傳遞標識符(ID)、過濾條件等;需要從 URL 直接定位的狀態(tài)。

11. 插槽(作用域插槽)

父組件通過作用域插槽接收子組件暴露的數(shù)據(jù),實現(xiàn)數(shù)據(jù)回傳渲染。

<!-- 子組件 -->
<template>
  <slot :data="list" :loading="isLoading" />
</template>
<!-- 父組件 -->
<Child>
  <template v-slot="{ data, loading }">
    <Spinner v-if="loading" />
    <List :items="data" />
  </template>
</Child>
  • 優(yōu)點:將渲染控制權交給父組件,但數(shù)據(jù)仍由子組件提供;非常靈活。
  • 缺點:只適用于父子關系,且邏輯偏向 UI 層的組合。
  • 場景:列表渲染、容器組件的動態(tài)布局、任何需要“數(shù)據(jù)在子組件,但渲染方式由父組件決定”的情形。

五、傳參方式對比總結

傳參方式方向/范圍響應式耦合度適用場景
props / emits父↔子?標準父子通信,單向/事件通知
v-model父↔子(雙向)?表單輸入、組件狀態(tài)即時同步
ref + defineExpose父→子?父組件命令式控制子組件行為
provide / inject祖先→后代? (引用)跨層級共享主題、配置等
$attrs父→子(透傳)?封裝基礎組件,透傳 HTML 屬性
Pinia / Vuex任意組件?極低全局狀態(tài)管理,多組件共享復雜狀態(tài)
Composables任意組件?極低輕量級跨組件共享狀態(tài)或邏輯
事件總線任意組件?極低極少數(shù)松耦合通信(不推薦)
路由傳參跨頁面?頁面跳轉攜帶 id、查詢參數(shù)等
作用域插槽子→父(數(shù)據(jù))?自定義子組件內(nèi)容的渲染邏輯

六、如何選擇?

沒有銀彈。實際開發(fā)中可以遵循以下準則:

  1. 首選最局部的方式:父子通信優(yōu)先用 props + emits;需要雙向綁定就用 v-model,避免過早使用全局狀態(tài)。
  2. 跨層級但不頻繁變動的數(shù)據(jù),用 provide/inject,再配合 readonly 或回調限定修改權限。
  3. 多組件共享同一業(yè)務狀態(tài),毫不猶豫使用 Pinia,它的結構化管理和調試能力會省去大量排查時間。
  4. 封裝基礎組件時,通過 useAttrs()v-bind="$attrs" 透傳屬性,保持靈活性。
  5. 避免事件總線,除非你十分清楚自己在做什么,且能將全局事件控制在一個極小范圍內(nèi)。

理解每種方式的邊界和開銷,能讓你在編寫組件時更加游刃有余。Vue3 提供的組合式 API 配合其豐富的通信機制,幾乎能夠優(yōu)雅地解決所有組件通信難題。

以上就是Vue3中常見的組件傳參方式大全及對比詳解的詳細內(nèi)容,更多關于Vue3組件傳參方式大全的資料請關注腳本之家其它相關文章!

相關文章

  • vue攔截器如何增加token參數(shù)

    vue攔截器如何增加token參數(shù)

    這篇文章主要介紹了vue攔截器如何增加token參數(shù)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • 在vue中獲取微信支付code及code被占用問題的解決方法

    在vue中獲取微信支付code及code被占用問題的解決方法

    這篇文章主要介紹了在vue中獲取微信支付code及code被占用問題的解決方法。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-04-04
  • Vue.js實現(xiàn)大轉盤抽獎總結及實現(xiàn)思路

    Vue.js實現(xiàn)大轉盤抽獎總結及實現(xiàn)思路

    這篇文章主要介紹了 Vue.js實現(xiàn)大轉盤抽獎總結及實現(xiàn)思路,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-10-10
  • 解決VUE自定義拖拽指令時 onmouseup 與 click事件沖突問題

    解決VUE自定義拖拽指令時 onmouseup 與 click事件沖突問題

    這篇文章主要介紹了解決VUE自定義拖拽指令時 onmouseup 與 click事件沖突問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-07-07
  • Vue實現(xiàn)簡易翻頁效果源碼分享

    Vue實現(xiàn)簡易翻頁效果源碼分享

    本文給大家分享了vue實現(xiàn)簡易翻頁效果,非常不錯,具有一定的參考借鑒價值,需要的朋友參考下吧
    2018-11-11
  • vue實現(xiàn)右鍵點擊彈框信息功能

    vue實現(xiàn)右鍵點擊彈框信息功能

    這篇文章主要介紹了vue實現(xiàn)右鍵點擊彈框信息功能方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • Vue組件之Tooltip的示例代碼

    Vue組件之Tooltip的示例代碼

    這篇文章主要介紹了Vue組件之Tooltip的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • vue3父組件使用ref獲取子組件的屬性和方法

    vue3父組件使用ref獲取子組件的屬性和方法

    在vue3中父組件訪問子組件中的屬性和方法是需要借助于ref,蘇哦一本文小編給大家介紹了vue3父組件如何使用ref獲取獲取子組件的屬性和方法,文中詳細的代碼講解,需要的朋友可以參考下
    2023-11-11
  • mpvue構建小程序的方法(步驟+地址)

    mpvue構建小程序的方法(步驟+地址)

    mpvue是一個使用Vue.js開發(fā)小程序的前端框架??蚣芑?Vue.js 核心,這篇文章主要介紹了mpvue構建小程序的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • vue3?hook重構DataV的全屏容器組件詳解

    vue3?hook重構DataV的全屏容器組件詳解

    這篇文章主要為大家介紹了vue3?hook重構DataV的全屏容器組件詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04

最新評論

垣曲县| 永清县| 饶河县| 阳信县| 八宿县| 三亚市| 观塘区| 天津市| 乡城县| 凤阳县| 灵寿县| 马山县| 彰化市| 永城市| 齐齐哈尔市| 腾冲县| 清丰县| 怀宁县| 台湾省| 文成县| 澄江县| 正镶白旗| 台南市| 淮滨县| 墨江| 连州市| 古田县| 景泰县| 墨竹工卡县| 金湖县| 巫山县| 宕昌县| 榆社县| 旌德县| 祁阳县| 琼结县| 桓仁| 金湖县| 仙游县| 长垣县| 台东市|