在 router.ts 中访问 Vuex 存储模块的状态
Posted
技术标签:
【中文标题】在 router.ts 中访问 Vuex 存储模块的状态【英文标题】:Accessing Vuex store module's state inside router.ts 【发布时间】:2019-03-22 14:51:45 【问题描述】:我按照this 教程使用 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,
;
store.ts:
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'
,这是有道理的,因为它没有定义,但它不应该在模块下查看,还是我没有定义模块正确吗?
【问题讨论】:
【参考方案1】:1
const isAuthed = store.state["UserProfile"].authed; // false
2
const state:any|State = store.state
const isAuthed = state.UserProfile.authed; // false
3
const isAuthed = (<any|State>store.state).UserProfile.authed; // false
【讨论】:
1 有同样的问题。 2 和 3 有效,但将它们转换为any
有点否定了打字稿的目的。赞成。【参考方案2】:
这是一个有效的解决方案,依赖 "vuex": "^4.0.2"
、"vue-router": "^4.0.10"
和 "vue": "^3.1.4"
。
将store
导入您的router
文件以访问您在模块中的状态:
import store from "@/store/store";
在我的例子中,模块名称是 authModule
,我访问了 token
的 state
,其中存储了 jwt:
let loggedIn = store.state.authModule.token;
【讨论】:
【参考方案3】:我建议进行双重演员。一对一,回到你真正想要的。请记住,在下面最后一个 router.ts 文件中,“store”是 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
存储/types.ts:
interface RootState
myOtherTestValue: string
export default RootState
export RootState
存储/索引.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)
在 router.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)
【讨论】:
【参考方案4】:编辑:似乎直接访问状态是这里的问题。线
const isAuthed = store.state.UserProfile.authed;
我相信这是因为它是命名空间的。解决方案是创建一个 getter。
const getters: GetterTree<ProfileState, RootState> =
user(state): User
return state.user
;
然后你就可以像访问它了
store.getters['UserProfile/user']
另外,请考虑使用 getter 来访问您的状态数据。参考Getters。
【讨论】:
我的模块中有 RootState:export const UserProfile: Module<ProfileState, RootState>
是的,但是您是否添加了 GetterTree、MutationTree 等?我相信即使是空的,也应该添加和导出它们。
我添加了所有代码(getter、mutations、action 等)同样的问题
我编辑了答案。您能否也尝试在最后导出主存储的空突变、动作和模块?依稀记得遇到过这个问题,一开始也是这样解决的。
我做了,同样的问题仍然存在以上是关于在 router.ts 中访问 Vuex 存储模块的状态的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Quasar 框架访问 Vuex 存储模块操作中的 Vue 路由器?
【笔记】使用Vite搭建Vue3(TypeScript版本)项目