/Pinia_Persisted_State

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.

Primary LanguageVue

Pinia Persisted State App

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.

Recommended IDE Setup

VSCode + Volar (and disable Vetur) + TypeScript Vue Plugin (Volar).

Type Support for .vue Imports in TS

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:

  1. Disable the built-in TypeScript Extension
    1. Run Extensions: Show Built-in Extensions from VSCode's command palette
    2. Find TypeScript and JavaScript Language Features, right click and select Disable (Workspace)
  2. Reload the VSCode window by running Developer: Reload Window from the command palette.

Customize configuration

See Vite Configuration Reference.

Project Setup

npm install

Compile and Hot-Reload for Development

npm run dev

Type-Check, Compile and Minify for Production

npm run build

Run Unit Tests with Vitest

npm run test:unit

Artwork from Pinia

pinia-plugin-persistedstate

Configurable persistence and rehydration of Pinia stores.

npm CI Coverage License

English | 简体中文

✨ Features

  • 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).

💡 Example

The following example illustrates how this pinia-plugin-persistedstate library was applied.

1. Pinia-plugin-persistedstate must be installed

With NPM:

npm i pinia-plugin-persistedstate

With Yarn:

yarn add pinia-plugin-persistedstate

2. In the main.ts the following lines are added:

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')

3. Create a store and put the persist attribute on it

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 });

4. Use the counterStore in a component or screen

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

Example 1

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

Example 2

⚠️ Limitations

There are some limitations that should be considered, more on those here.

🤝 Contributing

Run into a problem? Open an issue. Want to add some feature? PRs are welcome!

📝 License

Copyright © 2021-present Sacha Bouillez. This project is under MIT license.