如何重置PINIA状态的数据之一?

发布于 2025-01-24 09:35:14 字数 116 浏览 0 评论 0原文

我在设置页面上有一个设计,每个人都会使用HAVA重置按钮,现在我使用Pinia为Store库。 我kown $ reset是重置整个PINIA状态,那么,如何重置Pinia状态的数据之一?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

若沐 2025-01-31 09:35:14

我这样做的典型方法是:

const defaultState = {
  foo: 'bar'
}

export const useFoo = defineStore('foo', {
  state: () => ({ ...defaultState }),
  actions: {
    reset() {
      Object.assign(this, defaultState);
    }
  }
})

您获得初始状态和reset()操作,该操作重置了最初的任何状态。显然,您可以选择DefaultState中放入的内容。


如果您只想重置一个特定的状态道具,而无需触摸任何其他状态,则只需将默认值分配给它:

useFoo().foo = 'bar';

如果您发现它有用,也可以具有通用update,您可以在其中分配多个在一个呼叫中陈述的值:

actions: {
  update(payload) {
    Object.assign(this, payload)
  }
}

使用:

useFoo().update({ 
  foo: 'bar',
  // add more props if needed...
});

最后但并非最不重要的一点,lodash's pick可用于选择并选择重置的内容,从defaultState 值,而无需指定实际值:

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

使用以下内容:

useFoo().reset(['foo']);

仅重置foo 'bar',但不触摸当前值boo

重置两个(使用上面的操作):

useFoo().reset(['foo', 'boo']);

...或usefoo()。reset()usefoo()。reset([]),两个重置所有状态,因为键?长度条件是假的。

这是一个工作示例:

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>

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>

哭了丶谁疼 2025-01-31 09:35:14

上面的示例在属性已经更改时不会将一个属性重置为默认值。
那是因为DefaultState具有反应性,您需要复制DefaultState,以使其不再反应。

import _pick from 'lodash.pick';

const defaultState = {
  foo: 'bar',
};

export const useStore = defineStore('store', {
  state: () => ({...defaultState}),
  actions: {
    reset(keys) {
      Object.assign(this, keys?.length
        ? _pick(defaultState, keys)
        : defaultState // if no keys provided, reset all
      );
    }
  }
})

这样使用

useStore().reset(['foo']);

它现在将重置foo返回bar

Above example doesn't reset one property to the default value when the property is already changed.
That's because the defaultState is reactive, you need to copy the defaultState so it's not reactive anymore.

import _pick from 'lodash.pick';

const defaultState = {
  foo: 'bar',
};

export const useStore = defineStore('store', {
  state: () => ({...defaultState}),
  actions: {
    reset(keys) {
      Object.assign(this, keys?.length
        ? _pick(defaultState, keys)
        : defaultState // if no keys provided, reset all
      );
    }
  }
})

Use it like this

useStore().reset(['foo']);

This will now reset foo back to bar

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文