How to Use Pinia Store Data to Control a Component in Nuxt 3

931 views Asked by At

I have created an overlay in the shared layouts of my Nuxt 3 project, and I'm using v-model="isLoading" to control its visibility.

layouts/default.vue

<template>
    <div class="appContainer">
        <slot/>
    </div>

    <v-overlay 
        v-model="isLoading"
        class="align-center justify-center"
    >
        <v-progress-circular
            indeterminate
            size="64"
            :width="6"
            color="light-blue"
        ></v-progress-circular>
    </v-overlay>
</template>

<script setup>
import { useStore } from '/stores/store.js'
const store = useStore()
const isLoading = store.isLoading
</script>

I've also created an isLoading value in the stores/store.js file, and its default value is false.

stores/store.js


export const useStore = defineStore('piniaStore', () => {
  
  const isLoading = ref(false)

  function toggleLoading() {
    isLoading.value = !isLoading.value
  }

  return {
    isLoading,
    toggleLoading,
  }
})

If I want to open the overlay within a function in Login.vue, how can I do it? I tried using isLoading = !isLoading or toggleLoading, but it didn't work. I suspect that it might be an issue with updating the component rendering.

pages/Login.vue

<script setup>
import { useStore } from '/stores/store.js'

const store = useStore
let isLoading = store.isLoading

const loginRequest = () => {
    isLoading = true
};
</script>

<template>
    <v-form @submit="loginRequest">
        <v-input></v-input>
        <v-btn></v-btn>
    </v-form>
</template>
2

There are 2 answers

0
Everton Luis de Oliveira On

I think the one solution using nuxt 3, you are trying to control the visibility of an overlay using the isLoading variable from the store and a v-model binding.

For open this overlay within the loginRequest function in Login.vue, you will need to call the toggleLoading

<script setup> import { useStore } from '/stores/store.js'

const store = useStore() let isLoading = store.isLoading

const loginRequest = () => {
    store.toggleLoading();
</script>

<template>
<v-form @submit="loginRequest">
    <v-input></v-input>
    <v-btn></v-btn>
</v-form>
</template>

Called store.toggleLoading() in your request you will toggle isLoading

0
YUN0814 On

Follow-up: I made two changes, and after making them, the issue was resolved:

  1. In the file layouts/default.vue:
// const isLoading = store.isLoading
// Change to
const { isLoading } = storeToRefs(store)
  1. In pages/Login.vue:

Change store.toggleLoading to store.toggleLoading() to call this action.

Hope this helps others!