在router.ts中访问Vuex存储模块的状态



我按照本教程使用 TypeScript 设置了一个包含模块的 Vuex 存储。

到目前为止,我有:

vuex/types.ts

export interface RootState {
version: string;
}

vuex/user-profile.ts

import { ActionTree, Module, MutationTree } from 'vuex';
import { RootState } from './types';
interface User {
firstName: string;
uid: string;
}
interface ProfileState {
user?: User;
authed: boolean;
}
const state: ProfileState = {
user: undefined,
authed: false,
};
const namespaced: boolean = true;
export const UserProfile: Module<ProfileState, RootState> = {
namespaced,
state,
};

商店:

import Vue from 'vue';
import Vuex, { StoreOptions } from 'vuex';
import { UserProfile } from '@/vuex/user-profile';
import { RootState } from '@/vuex/types';
Vue.use(Vuex);
const store: StoreOptions<RootState> = {
state: {
version: '1.0.0',
},
modules: {
UserProfile,
},
};
export default new Vuex.Store<RootState>(store);

在我的router.ts中,我想像这样访问存储的authed状态:

import store from './store';
//...other imports...
const router = new Router({
//... route definitions...
});
router.beforeEach((to, from, next) => {
const isAuthed = store.state.UserProfile.authed;
if (to.name !== 'login' && !isAuthed) {
next({ name: 'login' });
} else {
next();
}
});

代码有效(应用程序正确重定向(,但是,编译器抛出错误说Property 'UserProfile' does not exist on type 'RootState',这是有道理的,因为它没有定义,但它不应该也查看模块下,还是我没有正确定义模块?

您需要将所有存储定义为 rootState 接口,如下所示:

export default interface RootState {
version: string,
UserProfile: any
}

您也可以从用户配置文件导入接口并使用,而不是任何接口。由于您不使用帕斯卡大小写作为文件名

这将告诉 rootState 需要一个名为 UserProfile 的 vuex 存储,具有任何类型或 UserProfile 接口。

我的 vuex 商店有一个根状态接口,如下所示:

export default interface RootState {
version: string,
config: any,
cart: any,
checkout: any,
cms: any,
product: any,
shipping: any,
user: any,
wishlist: any,
attribute: any,
ui: any,
newsletter: any,
category: {
current_path: string,
current_product_query: any,
current: {
slug: string,
name: string
},
filters: any
}
}

编辑:似乎直接访问状态是这里的问题。线

const isAuthed = store.state.UserProfile.authed;

我相信发生这种情况是因为它是命名空间的。解决方案是创建一个 getter。

const getters: GetterTree<ProfileState, RootState> = {
user(state): User {
return state.user
}
};

然后你可以像访问它一样

store.getters['UserProfile/user']

此外,请考虑使用 getter 来访问您的状态数据。请参阅Getters以供参考。

1

const isAuthed = store.state["UserProfile"].authed; // false

阿拉伯数字

const state:any|State = store.state
const isAuthed = state.UserProfile.authed; // false

3

const isAuthed = (<any|State>store.state).UserProfile.authed; // false

这是一个具有依赖关系的工作解决方案,"vuex": "^4.0.2""vue-router": "^4.0.10""vue": "^3.1.4"

store导入router文件以访问模块中的状态:

import store from "@/store/store";

在我的情况下,模块名称是authModule,我访问tokenstate,其中存储了 jwt:

let loggedIn = store.state.authModule.token;

我建议做一个双重转换。一个对任何人,一个回到你真正想要的。请记住,在下面的最后一个router.ts文件中,"store"是存储的一个实例,其他两个导入只是类型。

为了简洁起见,我省略了命名空间、状态、getter、操作、突变代码。它们只是对象结构

store/myModule/types.ts:

export default interface State {
testValue
}

store/myModule/index.ts:

import RootState from '../types'
const module: Module<State, RootState> = {
namespaced,
state,
getters,
actions,
mutations,
}
export default module

store/types.ts:

interface RootState {
myOtherTestValue: string
}
export default RootState
export { RootState }

store/index.ts:

import RootState from './types'
import myModule from './myModule'
export const cmStore: StoreOptions<RootState> = {
actions,
mutations,
state,
modules: {
myModule,
},
plugins,
}
export default new Vuex.Store<RootState>(cmStore)

在路由器.ts中:

import store from './store'
import RootState from './store/types'
import MyModuleState from './store/myModule/types'
// to get what you want typed how you want:
const myState = ((store.state as any).myModule as MyModuleState)
console.log(myState.testValue)

最新更新