Chapter 93: Vue ‘expose’ Option

The defineExpose macro (often just called the expose option or expose API)

This is not an option like props, data, computed or methods in the old Options API. It is a special macro (a function you call at the top level of <script setup>) that lets you choose which variables / functions from inside your <script setup> block will be publicly accessible to the parent component when it uses a template ref (ref=”myChild”).

In short:

By default, nothing inside <script setup> is exposed to the parent via template ref. defineExpose() is how you explicitly say: “Parent, you are allowed to reach in and touch these things.”

Why defineExpose exists – The Big Problem It Solves

Before Vue 3.2 / early <script setup> days, people were very confused:

  • In Options API → parent could do this.$refs.child.someMethod() because everything in methods was automatically exposed.
  • In <script setup> → nothing is exposed by default → this.$refs.child is basically an empty object → parents could not call child methods or read child refs/state.

→ Developers started doing ugly hacks:

  • this.$refs.child.$el (DOM access — bad)
  • emitting events everywhere (overkill)
  • using provide/inject globally (messy)

defineExpose fixes this cleanly and safely.

Basic Syntax – How to Use It

vue

Parent usage

vue

Important Rules & Gotchas (2026 Must-Know)

Rule / Gotcha Correct Behavior / Best Practice
defineExpose only works in <script setup> In Options API → everything in methods is auto-exposed (no need for defineExpose)
Only what you explicitly expose is accessible const secret = ref(42) → parent cannot reach it unless you expose it
You expose references / functions Expose count (the ref), not count.value (the raw number)
Parent accesses via ref.value childRef.value.reset() or childRef.value.count.value
TypeScript support Excellent — defineExpose<{ reset: () => void; count: Ref<number> }>()
Can expose computed? Yes — defineExpose({ fullName }) if fullName = computed(…)
Can expose props? Yes — but usually pointless (parent already knows them)
Still needed in 2026? Yes — whenever parent needs to call child methods or read child refs/state

Real-World Example – Modal Component with Exposed Methods

Child: Modal.vue (very common pattern)

vue

Parent – using exposed methods

vue

→ Parent can call childRef.open(), childRef.close(), childRef.confirm() directly

Quick Summary Table – defineExpose in 2026

Question Answer / Best Practice
Where is it used? Only inside <script setup> — not in Options API
What does it expose? Variables (ref/reactive/computed), functions, objects — anything you want parent to access
Does parent get reactivity? Yes — if you expose a ref or reactive, parent can watch/read .value
TypeScript support Excellent — defineExpose<{ open: () => void; isVisible: Ref<boolean> }>()
Still needed in 2026? Yes — whenever parent needs to call child methods or read child internal state/refs
Alternative if no expose? Emit events upward — parent handles everything (cleaner in many cases)

Pro Tips from Real Projects (Hyderabad 2026)

  • Use defineExposeonly when necessary — prefer events (emit) for most parent-child communication
  • Expose functions (open/close/reset/validate) much more often than exposing state (refs)
  • Exposing state (like isVisible) → useful when parent wants to watch child state
  • In UI libraries (modal, drawer, dropdown) → defineExpose({ open, close, toggle }) is standard
  • Never expose everything — keep public API minimal & documented
  • Combine with template ref (ref=”child”) — parent does child.value.open()

Your mini practice task:

  1. Create Modal.vue exactly as above with defineExpose({ open, close })
  2. Use it in parent with ref=”modalRef” → add buttons “Open Modal” and “Close Modal”
  3. Call modalRef.value.open() and modalRef.value.close() from parent
  4. Add isVisible to expose → watch it in parent and log changes

Any part confusing? Want full examples for:

  • Modal with defineExpose + TypeScript typing?
  • Exposing computed values & reactive objects?
  • defineExpose vs emit events comparison?
  • Real UI library component (drawer, dialog, tooltip) with expose?

Just tell me — we’ll build the next clean, exposed-API component together 🚀

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *