【问题标题】:Accessing Vuex store module's state inside router.ts在 router.ts 中访问 Vuex 存储模块的状态
【发布时间】: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',这是有道理的,因为它没有定义,但它不应该在模块下查看,还是我没有定义模块正确吗?

【问题讨论】:

    标签: typescript vue.js vuex vue-router vuex-modules


    【解决方案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 等)同样的问题
        • 我编辑了答案。您能否也尝试在最后导出主存储的空突变、动作和模块?依稀记得遇到过这个问题,一开始也是这样解决的。
        • 我做了,同样的问题仍然存在
        猜你喜欢
        • 1970-01-01
        • 2017-12-05
        • 1970-01-01
        • 2021-08-27
        • 2019-11-17
        • 2017-05-12
        • 2018-05-19
        • 2021-05-15
        • 2018-09-29
        相关资源
        最近更新 更多