Vuex getter всегда возвращает null - PullRequest
1 голос
/ 25 сентября 2019

Когда я использую vuex getter в моем компоненте vue.js, он возвращает мне ноль.

Вот мой код

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 Ответ

1 голос
/ 26 сентября 2019

Вы должны охранять свой доступ к authUser с помощью loggedIn.Например

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