Reputation: 577
I am trying to get into the way of things with Vue but I've got some troubles with:
1: I cannot get access to my getters from router/index.js file. (I can get access to it but it return like a function with returns function with I cannot call and get the value)
2: I cannot set up guard properly. With Angular it's much easier
What am I doing wrong here? Any suggestions?
Router code
/* 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;
Vuex index
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
}
});
auth module (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')
}
}
}
Upvotes: 8
Views: 9594
Reputation: 31
I faced the same problem...
Every time I tried to retrieve the getter's data inside the router it returned the function itself instead of the desired function's return value.
In my code I used to call the createStore
method inside the main.js file, but in order to be able to call the store's getters
inside the vue-router you need to refactor your code, calling createStore
in the same index.js file you declared it:
main.js file...
import store from './modules/index.js'
import { createStore } from 'vuex';
const mainStore = createStore(store)
app.use(store)
index.js file (Vuex store)...
const store = { ... store code here ... }
export default store
main.js file...
import store from './modules/index.js'
app.use(store)
index.js file (Vuex store)...
import { createStore } from 'vuex';
const store = createStore({ ... store code here ... })
export default store
Upvotes: 1
Reputation: 63139
It seems createNamespacedHelpers
is just complicating things. Import the store:
import store from '@/store'; // <-- aliased path
Use the getters like this:
const isAuthenticated = store.getters['auth/isAuthenticated'];
const authStatus = store.getters['auth/authStatus'];
const test = store.getters['auth/test'];
The first portion of the string is the Vuex module name, followed by the getter name.
Not only is this simpler to use, it's more readable and clear which module the getter comes from when studying the code.
Upvotes: 9