Vuex getter 总是返回 null

Posted

技术标签:

【中文标题】Vuex getter 总是返回 null【英文标题】:Vuex getter always return null 【发布时间】:2020-01-26 01:49:36 【问题描述】:

当我在我的 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】:

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

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

【讨论】:

好的,它对我有用,但为什么另一个组件中的相同代码在没有this.loggedIn 的情况下运行良好 该组件是否有条件渲染?

以上是关于Vuex getter 总是返回 null的主要内容,如果未能解决你的问题,请参考以下文章

将 Getter 传递给 Vuex Action 返回 null

Vuex Getters 是不是返回对状态的引用(数组、对象等)?

为啥我的 Vuex getter 在客户端返回 TRUE 而在服务器端返回 FALSE?

vuex状态管理

使用 Vuex getter 进行 Vuetify Select

Vuex - Getter