Problem:
I am having trouble with Vue 3. When I use a subcomponent and the data that is being used to generate the content is updated, the subcomponent does not reactively update. I am using the setup()
function for the subcomponent, and my understanding was that props in Vue 3 are reactive, so I am at a loss for where I am going wrong.
This is my parent component:
<q-markup-table :v-show="!isLoading">
<thead>
<tr>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr v-for="(detailedPerson, index) in people" :key="index">
<td>
<PersonLink :person="buildPerson(detailedPerson)"></PersonLink>
</td>
</tr>
</tbody>
</q-markup-table>
With the following method:
data() {
return {
people: {} as DetailedPerson[],
};
},
methods: {
buildPerson(detailedPerson: DetailedPerson): Person {
return {
slug: person.slug,
firstName: person.firstName,
lastName: person.lastName,
};
},
}
When the people list is updated, the PersonLink
does not update; it is acting as though the props are not reactive. This is the PersonLink
code:
<template>
<router-link :to="url">{{ name }}</router-link>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { NameFormatter } from 'src/common/formatters';
import { Person } from './person.models';
export default defineComponent({
props: {
person: {
required: true,
type: Object as () => Person,
},
},
setup(props) {
return {
url: `/person/${props.person.slug}`,
name: NameFormatter.formatInverseName(props.person),
};
},
});
</script>
What needs to be done to ensure reactivity when the subcomponent props are updated at the parent component level?
Solution:
Props are reactive, but you construct static values from them, so those values are not updated.
You must use a computed ref to create the url
and name
, like so:
import { defineComponent, computed } from 'vue';
setup(props) {
const url = computed(() => `/person/${props.person.slug}`);
const name = computed(() => NameFormatter.formatInverseName(props.person));
return {
url,
name,
};
}
Now url
and name
will update when their dependencies change, and so will anything that depends on them.