This project was created with the purpose of testing the pinia-plugin-persistedstate library which serves to maintain the state of pinia even if the page is reloaded, it maintains the state in the localStorage.
VSCode + Volar (and disable Vetur) + TypeScript Vue Plugin (Volar).
TypeScript cannot handle type information for .vue
imports by default, so we replace the tsc
CLI with vue-tsc
for type checking. In editors, we need TypeScript Vue Plugin (Volar) to make the TypeScript language service aware of .vue
types.
If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a Take Over Mode that is more performant. You can enable it by the following steps:
- Disable the built-in TypeScript Extension
- Run
Extensions: Show Built-in Extensions
from VSCode's command palette - Find
TypeScript and JavaScript Language Features
, right click and selectDisable (Workspace)
- Run
- Reload the VSCode window by running
Developer: Reload Window
from the command palette.
See Vite Configuration Reference.
npm install
npm run dev
npm run build
Run Unit Tests with Vitest
npm run test:unit
Artwork from Pinia
Configurable persistence and rehydration of Pinia stores.
- Persist Pinia stores with a friendly API inspired by
vuex-persistedstate
. - Highly customisable with custom storage, customer serializer, paths picking...
- Compatible with everything that uses Pinia.
- No external dependencies in a tiny package (<1kB gzipped).
The following example illustrates how this pinia-plugin-persistedstate library was applied.
With NPM:
npm i pinia-plugin-persistedstate
With Yarn:
yarn add pinia-plugin-persistedstate
piniaPluginPersistedstate is imported from pinia-plugin-persistedstate
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
Then an instance of pinia is created and then the piniaPluginPersistedstate is used
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)
Before mounting the application in the #app, this instance of pinia must be used
app.use(pinia)
The code would look like this
import './assets/main.css'
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
import App from './App.vue'
import router from './router'
const app = createApp(App)
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)
app.use(pinia)
app.use(router)
app.mount('#app')
For this example we use a store called useCounterStore which is in src/stores/counter.ts
import { ref } from 'vue'
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', () => {
const count = ref<number>(0);
const increment = () => {
count.value++;
}
const decrement = () => {
count.value--;
}
return { count, increment, decrement }
});
After the second parameter of the defineStore, that is, the function, where the key is closed, we must add the following parameter:
{ persist: true }
The counterStore will look like this:
import { ref } from 'vue'
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', () => {
const count = ref<number>(0);
const increment = () => {
count.value++;
}
const decrement = () => {
count.value--;
}
return { count, increment, decrement }
}, { persist: true });
Using a page that was already created I made an HTML to use the counterStore, its variables and methods src/views/HomeView.vue
<script setup lang="ts">
import { useCounterStore } from '@/stores/counter';
import { storeToRefs } from 'pinia';
const counterStore = useCounterStore();
const { count } = storeToRefs(counterStore);
</script>
<template>
<section>
<h1>Count: {{ count }}</h1>
<button @click="counterStore.decrement" class="btn btn-outline-success px-5 me-2" data-testid="decrement-button">
-
</button>
<button @click="counterStore.increment" class="btn btn-outline-success px-5" data-testid="increment-button">
+
</button>
</section>
</template>
This is what the application looks like running
If we check the localStorage in the application section when inspecting the page we can see that the store counter is saving or changing the count variable, we can reload the page and verify that the state of the page or component is being maintained
There are some limitations that should be considered, more on those here.
Run into a problem? Open an issue. Want to add some feature? PRs are welcome!
Copyright © 2021-present Sacha Bouillez. This project is under MIT license.