I have a child component in Vue.js that gets passed a prop from the parent component. While the child component can read the prop, it can not write to the prop without throwing a TypeScript read-only error. How do I let the child component write to the prop?
Here is an example parent component:
<template>
<ChildComponent :count="parentCount"></ChildComponent>
</template>
<script setup lang="ts">
const parentCount = ref(0);
</script>
And an example child component:
<template>
<h1>{{ count }}</h1>
</template>
<script setup lang="ts">
defineProps({
count: { type: Number, required: true }
});
</script>
You could use a store to manage the state of your application in a more elegant and easier way, Nuxt 3 has a fairly simple integration with Pinia, here is a link to that. @pinia/nuxt
A store is a global state that can be accessed and updated anywhere without having to pass props from the parent component to the child components, this is specially useful if you have deeply nested child components.
Please take a look at the Pinia documentation for more information but this probably fulfills your use case. Here's a simple example taken from Pinia docs.
// Install @pinia/nuxt and add it as a module in your nuxt.config.js
export default defineNuxtConfig({
modules: ['@pinia/nuxt'],
})
// stores/counter.js
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => {
return { count: 0 }
},
// could also be defined as
// state: () => ({ count: 0 })
actions: {
increment() {
this.count++
},
},
})
// Your component
<script setup>
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore()
counter.count++
// with autocompletion ✨
counter.$patch({ count: counter.count + 1 })
// or using an action instead
counter.increment()
</script>
<template>
<!-- Access the state directly from the store -->
<div>Current Count: {{ counter.count }}</div>
</template>