Vue 中父子組件之間最常用的業(yè)務(wù)交互場景
Vue 父子組件的核心交互邏輯圍繞「數(shù)據(jù)向下傳遞、事件向上觸發(fā)」展開,以下是實際業(yè)務(wù)中最常用的 5 類場景,均基于 Vue3 組合式 API(主流用法)演示:
場景 1:父組件向子組件傳遞數(shù)據(jù)(Props)
業(yè)務(wù)場景:父組件加載列表數(shù)據(jù),子組件負(fù)責(zé)展示單條數(shù)據(jù)(如商品卡片、用戶信息項)。
父組件(Parent.vue)
<template>
<div class="parent">
<h3>父組件</h3>
<!-- 向子組件傳遞商品數(shù)據(jù) -->
<Child :product="productInfo" />
</div>
</template>
<script setup>
import Child from './Child.vue'
// 父組件的數(shù)據(jù)源
const productInfo = {
id: 1001,
name: "Vue實戰(zhàn)教程",
price: 99,
stock: 200
}
</script>
子組件(Child.vue)
<template>
<div class="child">
<h4>子組件 - 商品展示</h4>
<p>商品ID:{{ product.id }}</p>
<p>商品名稱:{{ product.name }}</p>
<p>商品價格:¥{{ product.price }}</p>
</div>
</template>
<script setup>
// 接收父組件傳遞的props,指定類型(增強健壯性)
const props = defineProps({
product: {
type: Object,
required: true, // 必傳項
default: () => ({}) // 默認(rèn)值(防止未傳時報錯)
}
})
</script>
關(guān)鍵說明:
defineProps是 Vue3 組合式 API 的內(nèi)置方法,無需導(dǎo)入即可使用;- Props 支持類型校驗(String/Number/Object/Array 等),推薦顯式聲明,便于維護(hù);
- Props 是單向數(shù)據(jù)流,子組件不能直接修改父組件傳遞的 props(需通過事件通知父組件修改)。
場景 2:子組件向父組件傳遞數(shù)據(jù) / 觸發(fā)事件($emit)
業(yè)務(wù)場景:子組件的按鈕點擊、表單提交等操作,需要通知父組件處理(如子組件點擊「減庫存」按鈕,父組件更新庫存數(shù)據(jù))。
父組件(Parent.vue)
<template>
<div class="parent">
<h3>父組件 - 庫存:{{ productInfo.stock }}</h3>
<!-- 監(jiān)聽子組件觸發(fā)的reduceStock事件 -->
<Child
:product="productInfo"
@reduce-stock="handleReduceStock"
/>
</div>
</template>
<script setup>
import Child from './Child.vue'
import { ref } from 'vue'
// 改用ref聲明響應(yīng)式數(shù)據(jù)(便于修改)
const productInfo = ref({
id: 1001,
name: "Vue實戰(zhàn)教程",
price: 99,
stock: 200
})
// 處理子組件觸發(fā)的減庫存事件
const handleReduceStock = (num) => {
if (productInfo.value.stock > 0) {
productInfo.value.stock -= num
} else {
alert('庫存不足!')
}
}
</script>
子組件(Child.vue)
<template>
<div class="child">
<h4>子組件 - 操作區(qū)</h4>
<!-- 點擊按鈕觸發(fā)自定義事件,傳遞參數(shù)1 -->
<button @click="handleClick">減少1件庫存</button>
</div>
</template>
<script setup>
// 定義子組件可觸發(fā)的事件
const emit = defineEmits(['reduce-stock'])
// 點擊按鈕時,向父組件觸發(fā)事件并傳遞參數(shù)
const handleClick = () => {
emit('reduce-stock', 1) // 事件名 + 傳遞的參數(shù)
}
</script>
關(guān)鍵說明:
defineEmits用于聲明子組件可觸發(fā)的事件,支持?jǐn)?shù)組 / 對象形式(對象可做參數(shù)校驗);- 事件名推薦使用
kebab-case(短橫線命名),與模板中的監(jiān)聽格式一致; - 子組件可通過
emit傳遞任意類型的參數(shù)(數(shù)字、對象、數(shù)組等)。
場景 3:父組件調(diào)用子組件的方法(ref)
業(yè)務(wù)場景:父組件點擊按鈕,觸發(fā)子組件的內(nèi)部方法(如子組件的表單重置、數(shù)據(jù)刷新、彈窗關(guān)閉)。
父組件(Parent.vue)
<template>
<div class="parent">
<h3>父組件</h3>
<button @click="callChildMethod">調(diào)用子組件的方法</button>
<!-- 給子組件綁定ref標(biāo)識 -->
<Child ref="childRef" />
</div>
</template>
<script setup>
import Child from './Child.vue'
import { ref } from 'vue'
// 定義ref引用子組件實例
const childRef = ref(null)
// 父組件調(diào)用子組件方法
const callChildMethod = () => {
// 通過ref訪問子組件暴露的方法
childRef.value.resetForm()
}
</script>
子組件(Child.vue)
<template>
<div class="child">
<h4>子組件 - 表單區(qū)域</h4>
<input v-model="inputValue" placeholder="請輸入內(nèi)容" />
</div>
</template>
<script setup>
import { ref } from 'vue'
const inputValue = ref('')
// 子組件的內(nèi)部方法
const resetForm = () => {
inputValue.value = ''
alert('子組件表單已重置!')
}
// 暴露方法給父組件調(diào)用(關(guān)鍵)
defineExpose({
resetForm
})
</script>
關(guān)鍵說明:
- 父組件通過
ref綁定子組件,獲取子組件實例; - 子組件需通過
defineExpose顯式暴露方法 / 數(shù)據(jù),父組件才能訪問(Vue3 默認(rèn)隱藏子組件內(nèi)部屬性); - 適用于「父組件主動控制子組件行為」的場景,避免過度使用(優(yōu)先用 props/emit)。
場景 4:父子組件雙向綁定(自定義 v-model)
業(yè)務(wù)場景:自定義表單組件(如輸入框、開關(guān)、下拉框),需要和父組件的數(shù)據(jù)雙向同步(Vue2 的.sync語法在 Vue3 中已整合為 v-model)。
父組件(Parent.vue)
<template>
<div class="parent">
<h3>父組件 - 雙向綁定值:{{ inputValue }}</h3>
<!-- 自定義v-model綁定 -->
<Child v-model="inputValue" />
</div>
</template>
<script setup>
import Child from './Child.vue'
import { ref } from 'vue'
// 父組件雙向綁定的數(shù)據(jù)源
const inputValue = ref('初始值')
</script>
子組件(Child.vue)
<template>
<div class="child">
<h4>子組件 - 自定義輸入框</h4>
<!-- 輸入框值變化時,觸發(fā)update:modelValue事件 -->
<input
:value="modelValue"
@input="emit('update:modelValue', $event.target.value)"
/>
</div>
</template>
<script setup>
// 接收v-model的默認(rèn)props(modelValue)
const props = defineProps(['modelValue'])
// 定義更新事件(update:modelValue是固定命名)
const emit = defineEmits(['update:modelValue'])
</script>
進(jìn)階:自定義 v-model 名稱如果需要多個雙向綁定,可自定義 v-model 的名稱:
<!-- 父組件 --> <Child v-model:username="username" v-model:phone="phone" /> <!-- 子組件 --> <script setup> const props = defineProps(['username', 'phone']) const emit = defineEmits(['update:username', 'update:phone']) </script>
場景 5:子組件訪問父組件($parent,不推薦)
說明:Vue 官方不推薦直接使用$parent訪問父組件(破壞組件封裝性),僅作了解,優(yōu)先用 props/emit。
<!-- 子組件中 -->
<script setup>
import { getCurrentInstance } from 'vue'
// 獲取組件實例
const instance = getCurrentInstance()
// 訪問父組件數(shù)據(jù)/方法
console.log(instance.parent.proxy.productInfo)
</script>
總結(jié)
- 核心交互規(guī)則:父傳子用
props(單向數(shù)據(jù)流),子傳父用emit(事件觸發(fā)),這是 Vue 父子組件通信的最佳實踐; - 父調(diào)子方法:通過
ref + defineExpose實現(xiàn),適用于父組件主動控制子組件行為的場景; - 雙向綁定:Vue3 通過自定義
v-model(modelValue + update:modelValue)實現(xiàn),替代 Vue2 的.sync語法; - 避免直接使用
$parent/$children,會降低組件的獨立性和可維護(hù)性。
到此這篇關(guān)于Vue 中父子組件之間最常用的業(yè)務(wù)交互場景的文章就介紹到這了,更多相關(guān)Vue 父子組件交互內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue實現(xiàn)對highlight-current-row方式整行選中后修改默認(rèn)背景顏色
這篇文章主要介紹了vue實現(xiàn)對highlight-current-row方式整行選中后修改默認(rèn)背景顏色方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-11-11
Vue中的Object.defineProperty全面理解
這篇文章主要介紹了Vue中的Object.defineProperty全面理解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-04-04

