I have a design in setting page,every one of them hava reset button, now i using pinia to be store library.
I kown $reset
is reset the whole pinia state,so,how to reset one of data in pinia state?
The typical way I do this:
const defaultState = {
foo: 'bar'
}
export const useFoo = defineStore('foo', {
state: () => ({ ...defaultState }),
actions: {
reset() {
Object.assign(this, defaultState);
}
}
})
You get the initial state and a reset()
action which resets whatever state has to the initial. Obviously, you can pick and choose what you put in defaultState
.
If you only want to reset one particular state prop, without touching anything else, just assign the default value to it:
useFoo().foo = 'bar';
If you find it useful, you can also have a generic update
, where you can assign multiple values to state in one call:
actions: {
update(payload) {
Object.assign(this, payload)
}
}
Use it like:
useFoo().update({
foo: 'bar',
// add more props if needed...
});
Last, but not least, lodash
's pick
can be used to pick and choose what gets reset, from the defaultState
values, without having to specify the actual values:
import { pick } from 'lodash-es';
const defaultState = {
foo: 'bar',
boo: 'far'
};
export const useFoo = defineStore('foo', {
state: () => ({ ...defaultState }),
actions: {
reset(keys) {
Object.assign(this, keys?.length
? pick(defaultState, keys)
: defaultState // if no keys provided, reset all
);
}
}
})
use it like:
useFoo().reset(['foo']);
This only resets foo
to 'bar'
, but doesn't touch current value of boo
.
To reset both (using the action above):
useFoo().reset(['foo', 'boo']);
...or useFoo().reset()
or useFoo().reset([])
, both of which reset all the state, because the keys?.length
condition is falsey.
Here's a working example:
const { createPinia, defineStore, storeToRefs } = Pinia;
const { createApp, reactive, toRefs } = Vue;
const defaultState = {
foo: "bar",
boo: "far",
};
const useStore = defineStore("foobar", {
state: () => ({ ...defaultState }),
actions: {
reset(keys) {
Object.assign(
this,
keys?.length ? _.pick(defaultState, keys) : defaultState
);
},
},
});
const pinia = createPinia();
const app = createApp({
setup() {
const store = useStore();
const localState = reactive({
resetFoo: false,
resetBoo: false,
});
const resetStore = () => store.reset(
[
localState.resetFoo ? "foo" : null,
localState.resetBoo ? "boo" : null,
].filter((o) => o)
);
return { ...storeToRefs(store), ...toRefs(localState), resetStore };
},
});
app.use(pinia);
app.mount("#app");
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<script src="https://unpkg.com/vue-demi"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pinia/2.0.28/pinia.iife.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
<div id="app">
<input v-model="foo" />
<input v-model="boo" />
<pre v-text="JSON.stringify({foo, boo}, null, 2)"></pre>
<hr>
<label>
<input type="checkbox" v-model="resetFoo" />ResetFoo</label>
<label>
<input type="checkbox" v-model="resetBoo" />ResetBoo</label>
<button @click="resetStore">Reset</button>
</div>