Vue Pinia Store -如何获得初始状态?



我的piia store中有一个对象,如

import { defineStore } from "pinia";
export const useSearchStore = defineStore("store", {
state: () => {
return {
myobj: {
foo: 0,
bar: 2000,
too: 1000,
},
};
},
getters: {
changed() {
// doesn't work
return Object.entries(this.myobj).filter(([key, value]) => value != initialvalue
);
},
},
});

如何获得初始值来测试对象是否更改。或者我如何返回一个只有那些条目与初始状态不同的过滤对象?

我目前的解决方案:在一个已创建的钩子中,我创建了一个store对象的硬拷贝,以便进行比较。我想有一种更优雅的方式…

我已经这样做了(尽管我不知道是否有更好的方法来避免克隆而不复制您的初始状态)。

在外部定义初始状态并将其分配给如下变量;

const initialState = {
foo: 0,
bar: 2000,
too: 1000
}

那么您可以使用克隆来保留原始状态;

export const useSearchStore = defineStore("store", {
state: () => {
return {
myobj: structuredClone(initialState),
};
},
getters: {
changed: (state) => deepEquals(initialState, state.myobj);
},
});

,其中deepEquals是一个深度比较两个对象的方法(您必须实现)。我将使用lodash(npm i lodashnpm i @types/lodash --save-dev,如果你使用TypeScript)。

完整代码(带lodash);

import { defineStore } from "pinia";
import { cloneDeep, isEqual } from "lodash";
const initialState = {
foo: 0,
bar: 2000,
too: 1000
}
export const useSearchStore = defineStore("store", {
state: () => ({
myobj: cloneDeep(initialState)
}),
getters: {
changed(state) {
return isEqual(initialState, state.myobj);
},
},
});

如果您还想要两者之间的差异,您可以使用以下函数(_是lodash -import _ from "lodash");

function difference(object, base) {
function changes(object, base) {
return _.transform(object, function (result: object, value, key) {
if (!_.isEqual(value, base[key])) {
result[key] =
_.isObject(value) && _.isObject(base[key])
? changes(value, base[key])
: value;
}
});
}
return changes(object, base);
}

由https://gist.github.com/Yimiprod/7ee176597fef230d1451提供

编辑:

另一种方法是使用监视程序来订阅更改。这样做的缺点是,你要么必须接受你的状态被标记为"已更改";如果您将数据更改回初始状态。否则,您将不得不实现一个系统(可能使用堆栈数据结构)来维护更改列表,以便如果发生两个相互抵消的更改,那么您将将状态标记为"未更改"。您将不得不在状态中保留另一个变量(布尔值),该变量保存状态是否已更改/未更改-但这将更复杂实现,并且(取决于您的用例)不值得。

最新更新