State persistent in Browser storage #1863
-
What problem is this solvingIn browser extension development we are using browser.storage as a extension-specific way to persist user data and state it is NOT Window.localStorage How can we use browser.storage to persist pinia state? browser.storage is async. Chrome local storage: Proposed solutionDocumentation how to use browser.storage as a persistent storage for pinia state or even better plugin to use browser.storage in pinia. Describe alternatives you've consideredNo response |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 4 replies
-
For this you have to use https://vueuse.org/core/usestorageasync/#usestorageasync to create your own wrapper and put it within a store: export const useStore = defineStore('id', () => {
const state = useStorageAsync(...)
}) |
Beta Was this translation helpful? Give feedback.
-
import { defineStore } from 'pinia';
import { useLocalStorage } from '@vueuse/core';
import { merge } from 'lodash-es';
import { unref, ref, watch } from 'vue';
export const useStorageStore = defineStore('storage', {
state: () => {
const state = useLocalStorage(
'vue-use-local-storage',
{
name: 'Banana',
color: 'Yellow',
size: 'Medium',
count: 0,
obj: {
name: 'xzq',
},
},
// When you manually manipulate localStorage,
// if you don't have mergeDefaults, then you're not going to add it to state in response.
// https://vueuse.org/core/useStorage/#merge-defaults
{
mergeDefaults: (storageValue, defaults) =>
merge(defaults, storageValue),
}
);
let obj = ref(unref(state)?.obj);
watch(
obj,
(newObj) => {
unref(state).obj = newObj;
},
{ deep: true }
);
watch(
state,
(newState) => {
// When obj changes, state will be affected, thus changing storage;
// But when storage changes, only state will be affected, so we need to associate with obj.
obj.value = newState.obj;
},
{ deep: true }
);
return {
state,
obj,
};
},
getters: {},
actions: {},
});
<template>
<div>
<div>name: <input v-model="state.name" type="text" /></div>
<div>color: <input v-model="state.color" type="text" /></div>
<div>size: <input v-model="state.size" type="text" /></div>
<div>
nested obj.name: <input v-model="obj.name" type="text" />
<button @click="changeObj">changeObj</button>
</div>
<div>
count:
<input
v-model.number="state.count"
type="range"
min="0"
step="0.01"
max="1000"
/>
</div>
<div style="margin-top: 30px">
state:
<pre lang="json">{{ state }}</pre>
<!-- <pre lang="json">{{ storageStore.state }}</pre> -->
</div>
</div>
</template>
<script setup>
import { watch, toRefs } from 'vue';
import { useLocalStorage } from '@vueuse/core';
import { merge } from 'lodash-es';
import { useStorageStore } from '../../store/modules/storageStore';
const storageStore = useStorageStore();
const { state, obj } = toRefs(storageStore);
const changeObj = () => {
obj.value = { name: 'xxx', age: 18 };
};
</script>
|
Beta Was this translation helpful? Give feedback.
For this you have to use https://vueuse.org/core/usestorageasync/#usestorageasync to create your own wrapper and put it within a store: