首页 > 解决方案 > Vuex getter 总是返回 null

问题描述

当我在我的 vue.js 组件中使用 vuex getter 时,它为我返回 null。

这是我的代码

主布局.vue

<script>
    import NavBar from '@/components/NavBar.vue'
    import ToolBar from "@/components/ToolBar"
    import { mapActions, mapGetters } from 'vuex'

    export default {
        name: "MainLayout",
        components : {
            ToolBar, NavBar
        },
        data: () => ({
            drawer: null,
        }),
        computed: {
            ...mapGetters([
                'error',
            ]),
        },
        methods: {
            close() {
                this.$store.commit('SET_ERROR', null)
            },
        }
    }
</script>

<template>
    <div id="main">
        <v-navigation-drawer clipped v-model="drawer" app>
            <nav-bar></nav-bar>
        </v-navigation-drawer>
        <tool-bar @toggleDrawer="drawer = !drawer"/>
        <v-content>
            <v-container class="fill-height" fluid>
                <router-view></router-view>
            </v-container>
        </v-content>
        <v-snackbar :timeout="0" :value="error">
            {{ error }}
            <v-btn color="red" text @click="close">
                Close
            </v-btn>
        </v-snackbar>
    </div>
</template>

<style scoped>

</style>

这是 NavBar.vue

<script>
    import { mapGetters } from 'vuex'
    export default {
        data: () => ({

        }),
        computed: {
            ...mapGetters([
                'authUser'
            ]),
            isAdmin() {
                return this.authUser.role.name == 'admin'
            },
        }
    }
</script>

Vuex 模块 auth.js

import api from '@/api'
import {clearAccessToken, setAccessToken} from '@/auth'
import router from '@/router'

const state = {
    loading: null,
    user: null
}


const mutations = {
    SET_LOADING: (state, loading) => {
        state.loading = loading
    },
    SET_USER: (state, user) => {
        state.user = user
    }
}

const getters = {
    loading: state => {
        return state.loading
    },
    loggedIn: (state) => {
        return !!state.user
    },
    authUser: (state) => {
        return state.user
    },
}

const actions = {
    async login({commit, dispatch }, user) {
        commit('SET_LOADING', true)
        try {
            const data = await api.post('/api/auth/login', { user })
            setAccessToken(data.token)
            await dispatch('getUser')
            commit('SET_LOADING', false)
            router.push('/')
        } catch (e) {
            commit('SET_LOADING', false)
            dispatch('handleError', e)
        }
    },

    async getUser({commit, dispatch}) {
        try {
            const user = await api.get('/api/auth/user')
            commit('SET_USER', user.data)
            return user
        } catch (e) {
            clearAccessToken()
            dispatch('handleError', e)
        }
    },

    async logout({commit, dispatch}) {
        try {
            await api.post('/api/auth/logout')
            clearAccessToken()
            router.push('/login')
        } catch(e) {
            dispatch('handleError', e)
        }
    }
}

export default {
    namespaced: false,
    state,
    getters,
    actions,
    mutations,
}

当我运行此代码时,我有下一个错误

[Vue warn]: Error in render: "TypeError: Cannot read property 'role' of null"

但是如果我添加代码

isAdmin() {
    return this.authUser.role.name == 'admin'
},

在 ToolBaar 组件中(并从 NavBar 中删除)

<script>
    import { mapGetters } from 'vuex'
    export default {
        methods: {
            toggleDrawer () {
                this.$emit('toggleDrawer')
            },
            logout() {
                this.$store.dispatch('logout')
            }
        },
        computed: {
            ...mapGetters([
                'loggedIn',
                'authUser'
            ]),
            fullName() {
                return this.authUser.first_name + ' ' + this.authUser.last_name
            },
            isAdmin() {
                return this.authUser.role.name == 'admin'
            }
        },
    }
</script>

然后它运行良好,没有任何错误,所以我不知道这里有什么问题,在一个组件代码中运行良好,而在另一个它没有,如果我将它添加到 MainLayout 组件并isAdmin作为道具传递,那么它也可以工作。请帮我解决这个问题。

另外,我在路由器挂钩中调度用户

router.beforeEach(async(to, from, next) => {
    const needAuth = to.matched.some(record => record.meta.auth)
    function redirectToLogin() {
        next({
            path: '/login',
            query: { redirect: to.fullPath },
        })
    }

    if (!hasToken() && needAuth) {
        return redirectToLogin()
    }

    if (hasToken() && !store.getters.loggedIn) {
        try {
           const user = await store.dispatch('getUser')
            if (!user) {
                return redirectToLogin()
            }
        } catch(e) {}
    }

    next()
})

标签: vue.jsvue-componentvuexvue-routervuetify.js

解决方案


你应该保护你对authUserwith的访问loggedIn。例如

isAdmin() {
  return this.loggedIn && this.authUser.role.name == 'admin'
}

推荐阅读