Skip to content

Latest commit

 

History

History
133 lines (101 loc) · 4.67 KB

README.md

File metadata and controls

133 lines (101 loc) · 4.67 KB

pinia-plugin-persistedstate

Configurable persistence and rehydration of Pinia stores.

✨ Features

  • Persist Pinia stores with the same API as vuex-persistedstate.
  • Configurable per Pinia store.
  • Still compatible with Vue 2 and 3.
  • Super small (<1kB).

⚙️ Installing

  1. Install with your favourite package manager (pnpm, npm, yarn).
  2. Add the plugin to pinia:
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)

🚀 Usage

You just need to add the persist option to the store you want to be persisted as follows:

import { defineStore } from 'pinia'

export const useStore = defineStore('main', {
  state: () => {
    return {
      someState: 'hello pinia',
    }
  },
  persist: true
})

In case you want to configure how the data should be persisted, persist can take options:

  • key: string : Key to use in storage (defaults to the current store id).
  • storage : Storage like object to persist state to. Must have getItem, setItem and removeItem methods (defaults to localStorage).
  • paths: Array<string> : Array of dot-notation paths to partially persist the state, [] means no state is persisted (defaults to undefined and persists the whole state).
  • overwrite: boolean : Whether you want to ovewrite the initial state on hydration (defaults to false and patches the state).
  • beforeRestore: (context) => void : Hook executed (if set) before restoring the state from localstorage.
  • afterRestore: (context) => void : Hook executed (if set) after restoring the state from localstorage.
import { defineStore } from 'pinia'

export const useStore = defineStore('main', {
  state: () => {
    return {
      someState: 'hello pinia',
      nested: {
        data: 'nested pinia',
      },
    }
  },
  persist: {
    key: 'storekey',
    storage: window.sessionStorage,
    paths: ['nested.data'],
    overwrite: true,
    beforeRestore: (context) => {
      console.log('Before hydration...')
    },
    afterRestore: ({ store }) => {
      store.lastReload = new Date().toString()
    }),
  }
})

The config above will only persist the nested.data property in sessionStorage under storekey and will overwrite the state on hydration.

It will also execute the beforeRestore and afterRestore hooks before/after hydration.

⚠️ Limitations

References do not persist

Beware of the following:

const a = {
  1: 'one',
  2: 'two',
  ...
}
const b = a

// Before hydration 'a' and 'b'
// point to the same object:
a === b -> true

// After hydration (page reload)
// 'a' and 'b' are different objects
// with the same content:
a === b -> false

As a consequence, reactivity between a and b is lost.

To get around this you can exclude either a or b from persisting and use the afterRestore() hook to populate them after hydration. That way a and b have the same reference again and reactivity is restored after page reload.

🤝 Contributing

This project tries to bring vuex-persistedstate's API to Pinia but I did not bring the whole API yet.

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

👤 About the author

Feel free to contact me:

  • discord: PraZ#4184

📝 Licence

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