到目前为止,我发现的有关该主题的唯一信息就是这个article。
我正在尝试使用2个模块来实现商店。
export interface RootState {
/** root state props **/
}
const store: StoreOptions<RootState> = {
modules: {
foo,
bar,
},
};
export default new Vuex.Store<RootState>(store);
然后我同时拥有两个模块:
export interface FooState {
//(...)
}
export const foo: Module<FooState, RootState> = {
//(...)
};
export interface BarState {
//(...)
}
export const bar: Module<BarState, RootState> = {
//(...)
};
一切正常,直到出现一种情况,我需要从foo模块中获取吸气剂以访问条形状态:
export const getters: GetterTree<FooState, RootState> = {
getInfo: (state, {}, rootState) => number {
const value = rootState.bar.somevalue;
//(...)
},
};
我有一个错误的错误消息,解释rootState没有bar属性。经过一段时间的思考,我设法解决了更改原始RootState接口的错误:
export interface RootState {
/** root state props **/
foo: FooState;
bar: BarState;
}
它解决了问题,对IDE智能感知非常有用。
这个方法正确吗?要将所有模块添加到StoreOptions使用的RootState接口中?
而且,似乎似乎缺少有关这些类型化接口(StoreOptions,Module,GetterTree等)的文档:Vuex是否足够成熟,可以与打字稿一起使用?
编辑:我忘了提及:从组件访问存储时,我仍然需要转换this。$ store(但是可以用vuex-class最小化)。似乎有一个question未解决。我想到现在还没有其他解决方案,对吗?
答案 0 :(得分:1)
使用这些vuex导入,Vuex与Typescript完全兼容:
import {GetterTree, MutationTree, ActionTree} from "vuex"
下面的示例显示了在打字稿中使用vuex的最简单,最完整的方法。
主要存储文件:
import Vue from 'vue'
import Vuex from 'vuex'
import { GetterTree, MutationTree, ActionTree } from "vuex"
import MySubModule from '@/store/submodule'
Vue.use(Vuex)
class State {
userId: string | null = null;
}
const getters = <GetterTree<State, any>>{
};
const mutations = <MutationTree<State>>{
setUserId(state, payload) {
state.userId = payload;
}
};
const actions = <ActionTree<State, any>>{
fetchUserId(store) {
}
};
export default new Vuex.Store({
state: new State(),
mutations: mutations,
actions: actions,
modules: {
subModuleName: MySubModule,
//other submodules
}
})
SubModule存储文件:
import { GetterTree, MutationTree, ActionTree } from "vuex"
class State {
}
const mutations = <MutationTree<State>>{
};
const actions = <ActionTree<State, any>>{
};
const MySubModule = {
namespaced: true,
state: new State(),
mutations: mutations,
actions: actions
};
export default MySubModule;
希望能帮助您!
答案 1 :(得分:0)
我最终使用了空的rootState接口并动态添加了所有模块。它根本消除了跨模块通信的问题。让我解释一下。 我来自C#,所以我想消除字符串文字和动态类型。我是用vuex-typex做的。请注意,它是模块,因此您可以使用许多自定义内容,例如事件或帮助函数。这是我的简化示例:
import { getStoreBuilder, BareActionContext } from "vuex-typex";
import { LiteEvent } from "./utility/LiteEvent";
import { IRootState } from "../store";
import ModuleApi, { IBuildInfo } from "./ModuleApi";
export interface IModuleState {
builds: IBuildInfo[];
}
const moduleBuilder = getStoreBuilder<IRootState>().module<IModuleState >("branches", { builds: [] });
const buildsChanged: LiteEvent<void> = new LiteEvent<void>();
const ModuleStore = {
get state(): IModuleState { return stateGetter(); },
get lastBuildInfo(): IBuildInfo | null { return lastBuildInfoGetter(); },
// mutations
setBuilds: moduleBuilder.commit(setBuilds),
// actions
requestBuilds: moduleBuilder.dispatch(requestBuilds),
buildsChanged: buildsChanged.expose(),
};
export default ModuleStore;
// getters
const stateGetter = moduleBuilder.state();
const lastBuildInfoGetter = moduleBuilder.read(lastBuildInfo);
function lastBuildInfo(state: IBranchesState): IBuildInfo | null {
const len = state.builds.length;
return len > 0 ? state.builds[state.builds.length - 1] : null;
}
// mutations
function setBuilds(state: IBranchesState, payload: { newBuilds: IBuildInfo[] }): void {
state.builds = payload.newBuilds;
onBuildsChanged.trigger();
}
type ActionContext = BareActionContext<IModuleState, IRootState>;
// actions
async function requestBuilds({ state }: ActionContext): Promise<void> {
const builds = await RepoBrancesApi.getBuilds(state.currentBranch);
BranchesStore.setBuilds({ newBuilds: builds});
}
getStoreBuilder<IRootState>().registerModule(moduleBuilder.namespace);
如果您对LiteEvent感兴趣-敬上Jason Kleban's post
这是另一个vuex模块或其他地方的用法:
async function requestSelectedChartGeom(context: ActionContext, payload: { chartName: string }): Promise<void> {
const chartGeom = await ChartBoundApi.getBoundsForChart(ModuleStore.lastBuildInfo, payload.chartName);
...
}
ModuleStore.onBuildsChanged.on(s => {
CommitLogStore.requestCommits();
});
我不喜欢太多的存储模块代码(由于工作函数不能是匿名的,因此必须将getter / mutation / action定义与工作函数分开),但是没有动态类型和字符串文字,所以我很高兴