persisting pinia store within Quasar app
See original GitHub issueI’m trying to use this Pinia Plugin in my Quasar app (Vue 3 / TypeScript).
Out of the box everything works fine.
But when using a Quasar boot file the persisted state stops working. Refreshing the page wipes all the new values away.
I don’t know why the boot file breaks the persisted state plugin, but I have narrowed the culprit down to a single line…
This is how I am using Pinia with Quasar and adding the plugin:
src/store/index.ts
/* eslint-disable @typescript-eslint/no-unused-vars */
import { store } from 'quasar/wrappers';
import { createPinia, Pinia } from 'pinia';
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
declare module '@quasar/app' {
interface BootFileParams<TState> {
store: Pinia;
}
interface PreFetchOptions<TState> {
store: Pinia;
}
}
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
$store: import('pinia').Pinia;
}
}
export default store(function (_) {
const pinia = createPinia();
pinia.use(piniaPluginPersistedstate); // Pinia Plugin added here
return pinia;
});
And this is what my Pinia store looks like:
src/store/user.ts
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
state: () => {
return {
user: {
firstName: 'Mary',
},
};
},
persist: true, // Note that we are using a persisted state here
actions: {
setFirstName(firstName: string) {
this.user.firstName = firstName;
console.log('Name set to Pinia store: ', this.user.firstName);
},
getFirstName() {
if (!this.user.firstName) {
console.log('No name found in store. Setting "John" to Pinia store.');
this.user.firstName = 'John';
return this.user.firstName;
} else {
console.log('Name fetched from Pinia store: ', this.user.firstName);
return this.user.firstName;
}
},
},
});
Here is an example front-end page for fetching and setting the firstName:
src/pages/index.vue
<template>
<div>{{ firstName }}</div>
<q-form @submit="handleFirstNameSubmit">
<p>Change First Name</p>
<q-input v-model="firstNameInput" filled outline />
<q-btn label="Submit Name to Pinia Store" type="submit" />
</q-form>
<q-btn @click="handleFirstNameFetch" label="Fetch Name from Pinia Store" />
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { useUserStore } from 'src/store/user';
const userStore = useUserStore();
const firstName = ref<string>();
const firstNameInput = ref<string>();
const handleFirstNameSubmit = () => {
if (firstNameInput.value) {
userStore.setFirstName(firstNameInput.value);
}
};
const handleFirstNameFetch = () => {
firstName.value = userStore.getFirstName();
};
</script>
Up to this point everything works fine.
I can set firstName to the Pinia store, refresh the page, and the new name is still in Pinia.
But when trying to use const userStore = useUserStore(store)
inside a boot file like the example below, the persisted state stops working:
src/boot/auth.ts
import { boot } from 'quasar/wrappers';
import { useUserStore } from 'src/store/user';
export default boot(({ store }) => {
const userStore = useUserStore(store);
// Do some other authentication stuff, setting initial user store values etc, below here...
});
Any idea what’s going on? And how to fix it?
I think this plugin is much cleaner than using the alternate LocalStorage persisted state solution so I would love to get it working with Quasar.
Issue Analytics
- State:
- Created 2 years ago
- Comments:12 (8 by maintainers)
Top GitHub Comments
Hi, Quasar core team member here 👋
It’s about Pinia’s limitation about using plugins before the app is initialized: https://github.com/quasarframework/quasar/discussions/12736#discussioncomment-2338508
We will release first-party Pinia support soon, and mention this limitation on our docs, pointing to the Pinia documentation.
v2.1.0
now offers quasar helpers. Docs are also updated with how to use it!I kept it iso with the way the Nuxt helper is made for now.
Closing this for now? feel free to reopen if you feel like something is off/odd/broken