访问路由器.ts内Vuex存储模块的状态

xwmevbvl  于 2023-03-13  发布在  Vue.js
关注(0)|答案(5)|浏览(146)

我按照this教程使用TypeScript设置了一个包含模块的Vuex商店。
到目前为止我有:

变量/类型.ts

export interface RootState {
    version: string;
}

vuex/用户配置文件.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,
};

商店.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',这是有意义的,因为它没有定义,但它不应该在模块下寻找,或者我没有正确定义模块?

fivyi3re

fivyi3re1#

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

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

您也可以从UserProfile导入接口,并使用来代替any。因为您不使用pascal大小写的文件名
这将告诉rootState期望一个名为UserProfile的vuex存储,它具有任何类型或UserProfile接口。
我有一个vuex存储的rootstate接口,如下所示:

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
  }
}
guicsvcw

guicsvcw2#

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

const isAuthed = store.state.UserProfile.authed;

我相信这是因为它是命名空间的,解决方法是创建一个getter。

const getters: GetterTree<ProfileState, RootState> = {

    user(state): User {
        return state.user
    }

};

然后你就可以访问它

store.getters['UserProfile/user']

另外,请考虑使用getter来访问状态数据,参考Getters

xfyts7mz

xfyts7mz3#

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
qf9go6mv

qf9go6mv4#

这是具有依赖项"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;
kgqe7b3p

kgqe7b3p5#

我建议做一个双转换。一个到任意,一个回到你真正想要的。记住,在下面的最后一个router.ts文件中,“store”是商店的一个示例,另外两个导入只是类型。
为了简洁起见,我省略了命名空间、状态、getter、动作、变化代码,它们只是对象结构
存储/我的模块/类型.ts:

export default interface State {
    testValue
}

存储/我的模块/索引.ts:

import RootState from '../types'

const module: Module<State, RootState> = {
    namespaced,
    state,
    getters,
    actions,
    mutations,
}

export default module

存储/类型。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)

相关问题