Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Watcher is only fired once when watching prop in Vue3 composition API

I have a parent component Search that passes the prop query to a child component Results.

Search.vue

<template>
  <div>
    <input v-model="query" type="text" />
    <Results :query="query" />
  </div>
</template>

<script>
import { defineComponent } from "vue";
import Results from "./Results.vue";
export default defineComponent({
  name: "Search",
  components: { Results },
  data() {
    return {
      query: "",
    };
  },
});
</script>

Results.vue

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

<template>
  <div>{{ query }} ( {{ query.length }})</div>
</template>

<script setup>
import { defineProps, watch, computed } from "vue";
const { query } = defineProps({
  query: {
    type: String,
    default: "",
  },
});

const queryLength = computed(() => query.length);

watch(
  () => query,
  () => {
    console.debug("Watcher was fired.");
  }, {immediate: true}
);

watch(queryLength, () => {
  console.debug("Watcher was fired.");
});

</script>

The watcher for the query prop never fires, except when I add {immediate: true} to the watcher, but then it does not fire on updates. It also doesn’t do anything when I add a computed property based on the query prop.

The strange thing is that when displaying the query prop, the value is rendered.

Here’s the simplest version of my code. What am I doing wrong?

>Solution :

You cannot destructure props directly as you do in

const { query } = defineProps({...})

or, to be precise, you can do it, but the resulting values won’t be reactive – query will be a simple string. So the value will be rendered, but watchers (among other things) will not work.

To avoid the error, either do not destructure at all or use the toRefs() utility function:

const props = defineProps({...})
const { query } = toRefs(props);
// or for a single prop:
const query = toRef(() => props.query)
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading