如何从 vue-router 访问 vuex getter 并设置守卫?

Val*_*y o 5 vue-router vuex vuejs2

我正在尝试使用 Vue 解决问题,但我遇到了一些麻烦:

1:我无法从 router/index.js 文件访问我的 getter。(我可以访问它,但它像一个带有返回函数的函数一样返回,我无法调用并获取值)

2:我无法正确设置警卫。使用 Angular 就容易多了

我在这里做错了什么?有什么建议?

路由器代码

/* eslint-disable no-undef */
import Vue from "vue";
import VueRouter from "vue-router";
// import auth from '../store/modules/auth';
import { createNamespacedHelpers } from "vuex";
const { mapGetters } = createNamespacedHelpers("auth");
// import store from '../store';


Vue.use(VueRouter);

const routes = [
  {
    path: "/",
    name: "Home",
    component: () => import("../components/Home.vue"),
    meta: { requiresAuth: true }
  },
  {
    path: "/users",
    name: "Users",
    component: () => import("../components/Users/Users.vue"),
    meta: { requiresAuth: true }
  },
  {
    path: "/sign-in",
    name: "SignIn",
    component: () => import("../components/SignIn/SignIn.vue"),
  }
];

const router = new VueRouter({
  mode: "history",
  base: process.env.BASE_URL,
  routes
});

router.beforeEach((to, from, next) => {
  const storeGetters = { ...mapGetters(['isAuthenticated', 'authStatus', 'test']) };

  const isUserLoggedIn = storeGetters.isAuthenticated;

  if (to.matched.some(record => record.meta.requiresAuth)) {
    if (isUserLoggedIn) {
      console.log('user is authenticated');
      to; from;
      return next();
    } else {
      console.log('Access denied!');
      next({
        path: '/signIn',
        query: { redirect: to.fullPath }
      });
    }

    next({
      path: '/signIn',
      query: { redirect: to.fullPath }
    });

  } else {
    next();
  }

})

export default router;
Run Code Online (Sandbox Code Playgroud)

Vuex 索引

import Vue from "vue";
import Vuex from "vuex";
import modules from "./modules"

Vue.use(Vuex);

export default new Vuex.Store({
  strict: true,
  modules,
  state: {
    testState: 'State value'
  },
  getters: {
    test: state => state
  }
});
Run Code Online (Sandbox Code Playgroud)

身份验证模块(vuex)

import { apolloClient } from '@/vue-apollo';
import SignInGQL from "@/graphql/signIn.gql";

export default {
    namespaced: true,
    state: {
        token: null,
        authStatus: false
    },
    getters: {
        isAuthenticated: (state) => {
            console.log('state: ', state);
            return !!state.token;
        },
        authStatus: state => state.authStatus,
        test: state => state.authStatus
    },
    actions: {
        async signIn({ commit, dispatch }, formInput) {

            try {
                const { data } = await apolloClient.mutate({
                    mutation: SignInGQL,
                    variables: { ...formInput }
                })

                const { token } = data.signIn;
                await commit('setToken', token);
                localStorage.setItem('auth-token', token);
                await dispatch('setUser', token);
            } catch (e) {
                console.error(e)
            }
        },
        async setUser({ commit }, token) {
            const encodedPayload = token.split('.')[1];

            const { payload } = JSON.parse(atob(encodedPayload));

            // TODO: Set User information 
            await commit('signInUser', payload);
        }
    },
    mutations: {
        setToken(state, token) {
            state.token = token
        },
        signInUser(state, user) {
            console.log('authStatus: ', state.authStatus)
            state.authStatus = true
            state.user = { ...user }
            console.log('authStatus: ', state.authStatus)
        },
        logOutUser(state) {
            console.log('dispatched logOutUser')
            state.authStatus = ''
            state.token = '' && localStorage.removeItem('auth-token')
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Dan*_*Dan 7

这似乎createNamespacedHelpers只是使事情复杂化。导入商店:

import store from '@/store'; // <-- aliased path
Run Code Online (Sandbox Code Playgroud)

像这样使用吸气剂:

const isAuthenticated = store.getters['auth/isAuthenticated'];
const authStatus = store.getters['auth/authStatus'];
const test = store.getters['auth/test'];
Run Code Online (Sandbox Code Playgroud)

字符串的第一部分是 Vuex 模块名称,后跟 getter 名称。

这不仅使用起来更简单,而且在研究代码时更易读和更清楚 getter 来自哪个模块。

  • 在我看来,Vue 无疑是最好的框架。最干净、最简单。 (2认同)