引用vuex的store.js 使用里面的getter提示getter未定义

梨花猫
  • 95

1. 引用我在http.js文件引用的store.js 使用里面的getter提示getter未定义

2. http.js的代码

import axios from 'axios';

import store from '../../store/store.js'


if (process.env.NODE_ENV === 'development') {
    axios.defaults.baseURL = '127.0.0.1:8000';
} else if (process.env.NODE_ENV === 'debug') {
    axios.defaults.baseURL = '127.0.0.1:8000';
} else if (process.env.NODE_ENV === 'production') {
    axios.defaults.baseURL = '127.0.0.1:8000';
}
axios.defaults.timeout = 10000;

const token = store.getters('user/getUserToken');

console.log(token);

// console.log('store', store);
// console.log('token', store.getters('user/getUserToken'));
axios.interceptors.request.use(
    config => {

        // const token = store.state('user/token');
        console.log('token', store);
        // token && (config.headers.Authorization = token);
        return config;
    },
    error => {
        return Promise.error(error);
    });

axios.interceptors.response.use(
    response => {
        if (response.status === 200) {
            return Promise.resolve(response);
        } else {
            return Promise.reject(response);
        }
    },
    // 服务器状态码不是200的情况
    error => {
        if (error.response.status) {
            switch (error.response.status) {
                // 401: 未登录
                // 未登录则跳转登录页面,并携带当前页面的路径
                // 在登录成功后返回当前页面,这一步需要在登录页操作。
                case 401:
                    this.$router.replace({
                        path: '/login',
                        query: {redirect: router.currentRoute.fullPath}
                    });
                    break;
                // 403 token过期
                // 登录过期对用户进行提示
                // 清除本地token和清空vuex中token对象
                // 跳转登录页面
                case 403:
                    HeyUI.$Message.error('登录过期,请重新登录');
                    // 清除token
                    localStorage.removeItem('token');
                    store.commit('user/loginSuccess', null);
                    // 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面
                    setTimeout(() => {
                        this.$router.replace({
                            path: '/login',
                            query: {
                                redirect: router.currentRoute.fullPath
                            }
                        });
                    }, 1000);
                    break;
                // 404请求不存在
                case 404:
                    HeyUI.$Message('网络请求不存在');
                    break;
                // 其他错误,直接抛出错误提示
                default:
                    HeyUI.$Message(error.response.data.message);
            }
            return Promise.reject(error.response);
        }
    }
);


export default axios;

3. store.js中的代码

import Vue from 'vue'
import Vuex from 'vuex'
import user from '../store/common/userInfo'
import permission from '../store/common/permission'

Vue.use(Vuex);
export default new Vuex.Store({
    modules: {
        user,
        permission
    }
});

4. userinfo.js中的内容

import Vue from 'vue'

export default {
    namespaced: true,
    state: {
        user_info: null,
        // token: null
    },
    mutations: {
        updateUserInfo: ({state, payload}) => {
            window.localStorage.setItem('isLogin', true);
            state.user_info = payload;
        },
        loginSuccess: ({state, payload}) => {
            state.token = payload;
            // window.localStorage.setItem("token", payload)
            window.localStorage.setItem('isLogin', true);
        }

    },
    actions: {
        getUserInfo: async ({commit}) => {
            let userInfo = await Vue.prototype.$http.post(`/api/getUserInfo`, {}).then(res => {
                if (res.data.code === 4001) {
                    HeyUI.$Message.error(res.data.msg)
                }
                return res.data.data;
            }).catch(err => {
                if (err.response) {
                    HeyUI.$Message.error(err.response.statusText);
                    return;
                }
                HeyUI.$Message.error(err.message)
            });

            if (userInfo) {
                commit('updateUserInfo', userInfo)
            }

        }
    },
    getters: {
        getUserToken: (state) => {
            if (state.user_info) {
                return state.user_info.token
            }
            return {}
        }
    }
};

4. google浏览器插件vue 看到的vuex中的数据

图片描述

5. 结果

图片描述

为什么会这样呢

回复
阅读 2.1k
4 个回答
✓ 已被采纳

store.getters['user/getUserToken'] 试试

没太看懂。
以代码看的话,你这没有用到vuex的getter吧?
以我的的理解的话,你想拿到store里user的值?
this.$store.state.user就可以了。


以上回答适用问题修改前

const token = store.getters('user/getUserToken');

这一行打个断点,看看 store 里的方法,我有点不太记得确切的对象结构了。


另外补充一下,你这个是比较典型的错用 Vuex。

Vuex 里面存放的数据应该满足:

  1. 要在很多组件里使用
  2. 需要响应式

在你的场景下,想用 token 存储用户身份,并且在之后的请求中都带上,所以其实只有 axios 要用,不符合(1)。请求的时候带上即可,页面上不需要直接渲染,不符合(2)。所以这里不应该使用 Vuex,你直接把它放在任何全局对象里都可以。

modules里写的getter要用store.getter['模块名/方法名']调用
或者引入mapGetter同样需要模块名/方法名
另外vuex提供了createNamespacedHelper可以直接创建一个模块内的引用方法

import{createNamespacedHelpers} from vuex;
const {mapGetter} from createNamespacedHelpers('user')

这样的mapGetter引入不需要写模块名

你知道吗?

宣传栏