了解 Vue 3 的 defineExpose 用法與應用場景

前言

在 Vue 3 中,組件之間的溝通通常透過 props 和 emit 來實現。不過在某些情境下,父組件可能需要直接呼叫子組件的方法或存取特定資料。此時,就可以透過 defineExpose將子組件內部的變數或方法暴露給父組件去使用

本文將說明 defineExpose 的基本用法與適用場景,並透過範例幫助你理解如何在實際開發中靈活運用它。

defineExpose

defineExpose 是 Vue 3 中提供的 Composition API,用來指定哪些資料或方法要暴露給父組件存取使用。當父組件透過 ref$refs 引用子組件時,只有經過 defineExpose 暴露的內容才能被正常存取。

使用範例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!-- 子組件 -->
<template>
<div>count: {{ count }}</div>
<button @click="count++">點我 +1</button>
</template>

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

const count = ref(0);

const reset = () => {
count.value = 0;
};

// 將 count 和 reset 暴露給父組件
defineExpose({
count,
reset,
});
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!-- 父層 -->
<script setup>
import { ref, onMounted } from 'vue';
import Child from './Child.vue'

const childRef = ref(null);

const resetChild = () => {
if (childRef.value) {
childRef.value.reset(); // 呼叫子組件暴露的方法
}
};
</script>

<template>
<h2>我是子組件</h2>
<Child ref="childRef" />
<hr>
<h2>調用子組件的 Reset</h2>
<button @click="resetChild">重設子組件 count</button>
<p>父組件讀取子組件 count:{{ childRef?.count }}</p>
</template>

defineExpose 使用示意圖

小結

如上所示,defineExpose 可以幫助我們將子組件中的資料與方法暴露給父組件使用,這在進行元件封裝與可重用設計時非常實用。不過,也應該謹慎地選擇要暴露的內容,以避免破壞元件封裝性。

常見應用場景

  • 子組件需要讓父組件觸發特定方法(如 reset, validate, focus)。
  • 使用第三方元件庫(例如 element-plus, ant-design-vue)時,需要暴露某些控制介面。
  • 在表單中,父元件需要控制多個子元件的狀態或執行動作。

注意事項

  • 只有透過 ref$refs 取得的子組件實例才能存取這些暴露內容。
  • defineExpose 僅適用於 <script setup> 模式。
  • 被暴露的變數需要是響應式資料(如 refreactive),否則在父組件中不具備響應性。

總結

特性 說明
適用場景 父組件需要控制子組件的方法或讀取其狀態時
可暴露內容 任意變數、方法(ref、reactive、function 等皆可)
搭配方式 搭配 ref$refs 存取子組件實例中的暴露內容
設計建議 精準暴露、避免過度依賴、保持元件封裝

透過 defineExpose 可以大大提升元件間溝通的彈性與擴展性。希望透過這篇文章,你對其用途與使用方式有了更深入的理解,未來在開發中能更得心應手。