Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple instance of pinia store possible in same page or same component?

Tags:

vuejs3

pinia

I have a pinia store which is products store. I use it in products page to get the products list . I also use it in a hidden popup box of this page which is product creation component .

When I call the pinia action fetchProductsList(cat1) in create-product component it fetch products of cat1. But it also change the result of products in products page.

I want to use different instance of product store on products page and product creation component to get different result of products. But I am getting the same result.

Is there any way to create different instance of same pinia store in same page so that i can get different result for productStore.products as per my needs ??

    import { defineStore } from 'pinia'
    
    export const useProductsStore = defineStore('products', {
    
        state: () =>
         ({ 
           
           products: [],
    
           
         }),
    
        getters: {
            getProducts: state => state.products
        },
    
        actions: {
    
            async fetchProductsList(category){
    
                return new Promise((resolve,reject)=>{
    
                    axios.get(`/api/products?product_cat=${category}`)
                    .then((response) => { 
                        this.products = response.data 
                        resolve(response)
                    })
                    .catch((errors)=>{
                        reject(errors)
                    })
                })
                       
            },
    
          
        },

})
like image 668
Efthakhar Bin Avatar asked Sep 07 '25 16:09

Efthakhar Bin


2 Answers

To use multiple instances of the same store but without sharing the refs (state properties) you can do it like this:

This example is in the Vue "Composition API: setup()"

import { computed, ref } from 'vue'
import { defineStore } from 'pinia'

const myStore = () => {
  const myRef = ref('A ref is a state property')
  const myGetter = computed(() => 'computed is a getter')
  
  return {
    myRef,
    myGetter,
  }
}

// This is where the difference is to make unique stores:
export const useMyStore = (uniqueStoreName) => {
  let store = defineStore(uniqueStoreName, myStore)
  return store()
}

export default useMyStore

And then in your component use it with a unique name

<template></template>
<script setup>

import { storeToRefs } from 'pinia'
import useMyStore from '~/stores/myStore'

const props = defineProps({
  distinctiveStoreName: {
    type: String,
    required: false,
    default: () =>
      'every-component-needs-a-unique-store-name-if-you dont-want-to-share-the-state-refs',
  },
})

const myStore = useMyStore(props.distinctiveStoreName)
const {
  // Some refs from the store
  myRef,
} = storeToRefs(myStore)

// Use getters from the store
let value = myStore.myGetter

</script>

Maybe you can use a random generated store id every time but I think that is not the best solution because when your component un-mounts and then mounts again, it will again create a fresh store with the new random number so this could lead to memory/performance problems? (not sure though)

like image 124
Julesezaar Avatar answered Sep 10 '25 05:09

Julesezaar


Posva ( creator of Pinia ) suggests this here

const options = {}
defineStore('one', {...options})
defineStore('two', {...options})
like image 31
dantheman Avatar answered Sep 10 '25 06:09

dantheman