【问题标题】:Vuex Object Shows Null in Vue ComponentVuex 对象在 Vue 组件中显示为 Null
【发布时间】:2020-06-18 13:54:16
【问题描述】:

在我正在创建的应用程序中,我有一个基础商店,用于存储可能在整个应用程序中使用的对象,例如登录用户、验证错误等。

我的应用程序的特定部分还有其他命名空间模块。

当我的父组件被加载时,有一个 ajax 调用会拉入数据并将其提交到各个存储区。

export const instantiate = ({ commit, dispatch }) => {
    return axios.get('/setup/fetch')
        .then((response) => {
            dispatch('base/setLoggedInUser', response.data.user, { root: true })
            commit('setFetishesList', response.data.fetishes)
            commit('setColorsList', response.data.colors)
            commit('setRolesList', response.data.roles)
            commit('setGendersList', response.data.genders)
            commit('setOrientationsList', response.data.orientations)
            commit('setLookingsList', response.data.lookings)
            commit('setSeekingsList', response.data.seekings)
            commit('setBodiesList', response.data.bodies)
            commit('setHeightsList', response.data.heights)
            commit('setEthnicitiesList', response.data.ethnicities)
            commit('setHairsList', response.data.hairs)
            commit('setEyesList', response.data.eyes)
            commit('setPiercingsList', response.data.piercings)
            commit('setTattoosList', response.data.tattoos)
            commit('setSmokingsList', response.data.smokings)
            commit('setDrinkingsList', response.data.drinkings)
            commit('setStatusesList', response.data.statuses)
            commit('setEducationsList', response.data.educations)
            commit('setAgesList', response.data.ages)

        return Promise.resolve(response)
    })
}

然后我使用映射的 getter 来访问我的商店中的项目。

computed: {
    ...mapGetters({
        user: 'base/getUser',
        fetishList: 'setup/getFetishesList',
        localeData: 'setup/getLocale',
        colorsList: 'setup/getColorsList',
        rolesList: 'setup/getRolesList',
        genderList: 'setup/getGendersList',
        orientationList: 'setup/getOrientationsList',
        lookingList: 'setup/getLookingsList',
        seekingList: 'setup/getSeekingsList',
        validation: 'base/getValidationErrors',
    }),
}

除了我的用户对象之外,一切都按预期工作。

在我的 Vue 检查器中,我可以看到用户对象按预期正确存储在 Vuex 中,但是当我 console.log(this.user) 时我得到 null 并且每当我尝试访问用户属性时,我都会收到控制台错误。

谁能解释为什么会发生这种情况,我以前从未见过这种情况,也不知道我在寻找什么?

谢谢。

【问题讨论】:

    标签: vue.js vuex


    【解决方案1】:

    我的猜测是您的 dispatch()(Vue.js 操作总是被认为是异步的)没有正确完成。这就是我将用一个警告重写它的方式:

    您的 base/setLoggedInUserVuex 操作必须返回一个 Promise 才能正常工作。

    /*
    export const instantiate = ({ commit, dispatch }) => {
        return axios.get('/setup/fetch')
            .then((response) => {
                dispatch('base/setLoggedInUser', response.data.user, { root: true })
                commit('setFetishesList', response.data.fetishes)
                commit('setColorsList', response.data.colors)
                commit('setRolesList', response.data.roles)
                commit('setGendersList', response.data.genders)
                commit('setOrientationsList', response.data.orientations)
                commit('setLookingsList', response.data.lookings)
                commit('setSeekingsList', response.data.seekings)
                commit('setBodiesList', response.data.bodies)
                commit('setHeightsList', response.data.heights)
                commit('setEthnicitiesList', response.data.ethnicities)
                commit('setHairsList', response.data.hairs)
                commit('setEyesList', response.data.eyes)
                commit('setPiercingsList', response.data.piercings)
                commit('setTattoosList', response.data.tattoos)
                commit('setSmokingsList', response.data.smokings)
                commit('setDrinkingsList', response.data.drinkings)
                commit('setStatusesList', response.data.statuses)
                commit('setEducationsList', response.data.educations)
                commit('setAgesList', response.data.ages)
    
            return Promise.resolve(response)
        })
    }
    */
    
    export const instantiate = ({ commit, dispatch }) => {
        return axios.get('/setup/fetch')
            .then((response) => Promise.all([
              dispatch('base/setLoggedInUser', response.data.user, { root: true }),
              Promise.resolve(response)
            ]))
            .then(([dispatchResponse, response]) => {
                commit('setFetishesList', response.data.fetishes)
                commit('setColorsList', response.data.colors)
                commit('setRolesList', response.data.roles)
                commit('setGendersList', response.data.genders)
                commit('setOrientationsList', response.data.orientations)
                commit('setLookingsList', response.data.lookings)
                commit('setSeekingsList', response.data.seekings)
                commit('setBodiesList', response.data.bodies)
                commit('setHeightsList', response.data.heights)
                commit('setEthnicitiesList', response.data.ethnicities)
                commit('setHairsList', response.data.hairs)
                commit('setEyesList', response.data.eyes)
                commit('setPiercingsList', response.data.piercings)
                commit('setTattoosList', response.data.tattoos)
                commit('setSmokingsList', response.data.smokings)
                commit('setDrinkingsList', response.data.drinkings)
                commit('setStatusesList', response.data.statuses)
                commit('setEducationsList', response.data.educations)
                commit('setAgesList', response.data.ages)
    
            return Promise.resolve(response)
        })
    }

    【讨论】:

    • 非常感谢,我会试一试。是否可以直接提交到另一个命名空间?除了分派到备用模块之外,我什么都没做。
    • @VinceKronlein => 我认为你不能提交到另一个命名空间。我很确定你必须使用一个动作(就像你正在做的那样)才能做到这一点,但同样,我对这个答案不是 100% 有信心。
    • Afaik 直接提交是一种反模式。提交只能在操作中触发。
    • 提交是从动作触发的,只是从另一个命名空间中的动作触发。仅供参考,它运行良好,我将状态用户从 null 切换到空数组,一切都已解决。然后我将调度切换为提交,我已经完美了。
    • @VinceKronlein 你可以使用 {root: true} 选项提交到其他命名空间,如下所示: commit('module/mutation', payload, { root: true }) 发现于stackoverflow.com/questions/44618440/…
    【解决方案2】:

    这里有两个主要的可能性:

    第一个是您可能没有正确定义用户 getter。

    第二个,console.log 在此操作设置的数据之前执行:

     dispatch('base/setLoggedInUser', response.data.user, { root: true })
    

    Vuex 操作是异步的,因此 setLoggedInUser 可以在执行 console.log(以及给您错误的代码)之前启动,但此时可能尚未收到实际数据(它将是未定义的)。

    如果是这种情况,请将以下条件添加到模板部分或正在使用您遇到这些错误的代码块的组件:

     v-if="user"
    

    这将使 Vue 等待映射的 getter 用户有一个值来挂载所述模板段或组件,避免尝试访问未定义的属性。

    【讨论】:

    • 感谢您的建议,非常好。事实证明,在我的状态下,我有 user:null,一旦我将其更改为 user:[],所有问题都会自行解决。
    • @VinceKronlein 好吧,那就更好了,只要该默认值对您的所有情况都有效。例如,如果您尝试执行 this.user[1] 之类的操作而不检查用户数据是否已设置,那么您将遇到类似的问题。
    猜你喜欢
    • 2019-12-12
    • 2017-05-26
    • 2018-02-04
    • 2020-08-21
    • 2020-08-11
    • 2011-04-25
    • 2021-04-10
    • 2020-05-04
    • 2020-03-15
    相关资源
    最近更新 更多