Search code examples
typescriptvue.jsvuejs3nuxt.jsnuxt3.js

How To Use Refs As Props in Nuxt 3


I am making a web app using Nuxt 3, and I have a few refs in the app.vue file. I pass these refs as attributes to the NuxtPage element, and can then access them in all files in the pages directory. The issue is, that I want to change the value of the ref from the pages, but Typescript gives an error saying it is a read-only property. I have tried adjusting the type of the prop in the page component and using Object as [ref type], but that still doesn't work.

Is there some way I could do this, or if this is not best practice, an alternative to achieve the same behavior?

Thanks!


Solution

  • You could use a store to manage state 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 at 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>