在 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,我访问了 tokenstate,其中存储了 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&lt;ProfileState, RootState&gt; 是的,但是您是否添加了 GetterTree、MutationTree 等?我相信即使是空的,也应该添加和导出它们。 我添加了所有代码(getter、mutations、action 等)同样的问题 我编辑了答案。您能否也尝试在最后导出主存储的空突变、动作和模块?依稀记得遇到过这个问题,一开始也是这样解决的。 我做了,同样的问题仍然存在

以上是关于在 router.ts 中访问 Vuex 存储模块的状态的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Quasar 框架访问 Vuex 存储模块操作中的 Vue 路由器?

【笔记】使用Vite搭建Vue3(TypeScript版本)项目

指定要在组件中使用的 Vuex 存储

Vuex/Vuejs:在 vuex 存储中访问 localStorage

无法在模块之外访问 Vuex getter

如何在 Vuex 商店模块状态中访问“this”