Vuex getter始终返回null

时间:2019-09-25 19:52:43

标签: vue.js vue-component vuex vue-router vuetify.js

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

这是我的代码

MainLayout.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()
})

1 个答案:

答案 0 :(得分:1)

您应该使用authUser保护对loggedIn的访问。例如

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