Home > Net >  Using Vue3 Reactivity Transform macros and defineExpose() breaks the ref's reactivity
Using Vue3 Reactivity Transform macros and defineExpose() breaks the ref's reactivity

Time:10-08

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>

Live example on Vue playground

CodePudding user response:

Try to expose properties in child with reactivity ref and in parent access it via template ref:

<template>
  <input v-model="text" />
</template>

<script setup>
  import {ref} from "vue"
  const text = ref('hello');
  defineExpose({ text })
</script>

CodePudding user response:

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>

Working example on Vue playground

  • Related