Search code examples
vue.jsvue-componentvuejs3vue-composition-apivue-script-setup

Watch child properties from parent component in vue 3


I'm wondering how I can observe child properties from the parent component in Vue 3 using the composition api (I'm working with the experimental script setup).

<template>//Child.vue
  <button 
    @click="count++" 
    v-text="'count: ' + count" 
  />
</template>

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

let count = ref(1)
</script>
<template>//Parent.vue
  <p>parent: {{ count }}</p> //update me with a watcher
  <Child ref="childComponent" />
</template>


<script setup>
import Child from './Child.vue'
import { onMounted, ref, watch } from 'vue'

const childComponent = ref(null)
let count = ref(0)

onMounted(() => {
  watch(childComponent.count.value, (newVal, oldVal) => {
    console.log(newVal, oldVal);
    count.value = newVal
  })
}) 
</script>

I want to understand how I can watch changes in the child component from the parent component. My not working solution is inspired by the Vue.js 2 Solution asked here. So I don't want to emit the count.value but just watch for changes.

Thank you!


Solution

  • The Bindings inside of <script setup> are "closed by default" as you can see here.

    However you can explicitly expose certain refs. For that you use useContext().expose({ ref1,ref2,ref3 })

    So simply add this to Child.vue:

    import { useContext } from 'vue'
    
    useContext().expose({ count })
    

    and then change the Watcher in Parent.vue to:

    watch(() => childComponent.value.count, (newVal, oldVal) => {
        console.log(newVal, oldVal);
        count.value = newVal
      })
    

    And it works!