Vue3 + Vuex4 + typescript项目 router 全局防卫获取不了 state 下子模块的属性

报错如下:

img

大概代码如下:

@/store/modules/moduleTypes.ts

export interface UserState {
    auth: any,
    name: string,
    login: boolean
};

@/store/rootTypes.ts

import * as moduleTypes from './modules/moduleTypes';

export interface AllStateTypes extends RootState {
    user: moduleTypes.UserState
}

export default interface RootState {
    version: string
}

@/store/index.ts

export default createStore<RootState>({
  state: {
    version: "1.0.0"
  },
  getters,
  // mutations: {
  // },
  // actions: {
  // },
  modules: {
    user
  },
  plugins: [createPersistedState({storage:window.sessionStorage})]

});

export const key: InjectionKey<Store<RootState>> = Symbol('vue-store');

export function useStore<T=AllStateTypes>(){
  return baseUseStore<T>(key);
}

@/router/index.ts

const router = createRouter({
  history: createWebHashHistory(process.env.VUE_APP_API_URL),
  routes
})

// 全局守卫
router.beforeEach(guards.globalGuard);

export default router

@/router/guard.ts


import { useStore } from "@/store/index";

export default {
    globalGuard: (to: any, from: any, next: any) => {
        console.log("to: " + JSON.stringify(to));
        const store = useStore();
        // 我们在路由的配置中使用一个元数据 meta.requiresAuth 来标识是否需要认证
        if (to.matched.some((record: any) => {
            console.log("meta: " + JSON.stringify(record.meta));
            return record.meta.requireAuth
        })) {
            // 如果路由需要认证,则检查是否已经登录,如果没有,导航到登录页面   
            console.log("isLogin: " + store.state.user.login);
            if (!store.state.user.login) {
                next({
                    path: "/login",
                });
            } else {
                next();
            }
        } else {
            next(); // 确保在其他情况下调用 next()!
        }
    }
}

main.ts

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store, {key} from './store'
import Antd from 'ant-design-vue';

const app = createApp(App as any);
app.use(store, key).use(router).use(Antd).mount('#app')

use Store的导入改为import { useStore} from " vuex"

使用下面方式解决了


import store from "@/store";

const userState = (store as any).state.user;
export default {
    globalGuard: (to: any, from: any, next: any) => {
        console.log("to: " + JSON.stringify(to));
        // 我们在路由的配置中使用一个元数据 meta.requiresAuth 来标识是否需要认证
        if (to.matched.some((record: any) => {
            console.log("meta: " + JSON.stringify(record.meta));
            return record.meta.requireAuth
        })) {
            // 如果路由需要认证,则检查是否已经登录,如果没有,导航到登录页面
            // const store = useStore();
            console.log("isLogin: " + userState.login);
            if (!userState.login) {
                next({
                    path: "/login",
                });
            } else {
                next();
            }
        } else {
            next(); // 确保在其他情况下调用 next()!
        }
    }
}