What Causes This Warning?
This warning occurs when you call expose() more than once in a component’s setup function. Vue only processes the first expose() call and ignores subsequent ones.
The Problem
export default {
setup(props, { expose }) {
// ❌ Multiple expose calls
expose({ methodA })
expose({ methodB }) // Warning! This is ignored
}
}
The Fix
Single expose() Call
export default {
setup(props, { expose }) {
function methodA() { /* ... */ }
function methodB() { /* ... */ }
const publicValue = ref(0)
// ✅ Single expose with all public members
expose({
methodA,
methodB,
publicValue
})
}
}
With defineExpose (Script Setup)
<script setup>
function methodA() { /* ... */ }
function methodB() { /* ... */ }
const publicValue = ref(0)
// ✅ Single defineExpose call
defineExpose({
methodA,
methodB,
publicValue
})
</script>
Common Scenarios
Conditional Exposure
// ❌ Wrong - multiple exposes
export default {
setup(props, { expose }) {
if (props.advanced) {
expose({ advancedMethod })
}
expose({ basicMethod }) // Ignored!
}
}
// ✅ Correct - single expose
export default {
props: ['advanced'],
setup(props, { expose }) {
const methods = {
basicMethod
}
if (props.advanced) {
methods.advancedMethod = advancedMethod
}
expose(methods)
}
}
Composable Integration
// ❌ Each composable calling expose
function useFeatureA(expose) {
expose({ featureA }) // Wrong!
}
function useFeatureB(expose) {
expose({ featureB }) // Wrong!
}
// ✅ Collect and expose at component level
function useFeatureA() {
return { featureA }
}
function useFeatureB() {
return { featureB }
}
export default {
setup(props, { expose }) {
const a = useFeatureA()
const b = useFeatureB()
expose({
...a,
...b
})
}
}
Building Object Gradually
<script setup>
// ✅ Build object before exposing
const exposed = {}
exposed.method1 = () => { /* ... */ }
exposed.method2 = () => { /* ... */ }
exposed.value = ref(0)
defineExpose(exposed)
</script>
When to Use expose()
// Use expose to limit what parent can access via template ref
export default {
setup(props, { expose }) {
const internalState = ref('private')
const publicState = ref('public')
function internalMethod() { /* private */ }
function publicMethod() { /* accessible via ref */ }
// Only publicState and publicMethod accessible
expose({
publicState,
publicMethod
})
return { internalState, publicState }
}
}
<!-- Parent -->
<template>
<ChildComponent ref="child" />
</template>
<script setup>
const child = ref(null)
onMounted(() => {
// Only exposed members available
child.value.publicMethod() // ✅ Works
child.value.publicState // ✅ Works
child.value.internalState // ❌ Undefined
child.value.internalMethod // ❌ Undefined
})
</script>
Quick Checklist
- Call
expose()ordefineExpose()only once - Combine all public members in a single object
- Build the expose object before the call if needed
- Composables should return values, not call expose