In the following example, the $ref pointing to the child's text does not persist when it is exposed using defineExpose(). Changes to the <input>
are ignored. The parent can only access the initial value ("hello"
).
The expected behavior is seen when using the standard ref()
instead of Reactivity Transform $ref()
What am I doing wrong here?
App.vue
<template>
<Child ref="child" />
<p>Child text: {{child?.text}}</p>
</template>
<script setup>
import Child from './Child.vue'
const child = $ref();
</script>
Child.vue
<template>
<input v-model="text" />
</template>
<script setup>
const text = $ref('hello');
defineExpose({ text })
</script>
Here's what I found by digging deeper in the Vue docs:
While reactive variables relieve us from having to use .value everywhere, it creates an issue of "reactivity loss" when we pass reactive variables across function boundaries.
To remedy this, they have $$()
. Using it during defineExpose()
solves my issue.
<template>
<input v-model="text" />
</template>
<script setup>
const text = $ref('hello');
defineExpose(
$$({ text })
)
</script>