如何用 Nuxt 控制 Vuex 的执行顺序

Posted

技术标签:

【中文标题】如何用 Nuxt 控制 Vuex 的执行顺序【英文标题】:How to control Vuex execution order with Nuxt 【发布时间】:2022-01-22 19:37:26 【问题描述】:

我正在使用 Nuxt、Laravel API 和 FirebaseAuthentication 创建一个餐厅预订应用程序。

我创建了一个喜欢/不喜欢的功能,如果登录用户点击卡片上的心形按钮,心形颜色会变为红色。

该函数有时可以正常工作,但有时在重新加载时在 store/auth.js 中的 getLikes() 处出错。

GET http://localhost:8000/api/v1/users/ 405(不允许的方法)

获取点赞餐厅的API路径是api/v1/likes/user_id,bit由于没有存储用户信息,所以按照如下流程获取信息。

    获取用户信息。 (api/v1/users/uid)

    获取登录用户喜欢的餐厅列表。 (api/v1/likes/user_id)

当我查看 Vuex 的执行历史时,执行顺序取决于它是成功还是失败。

成功后,auth/setUserId 的执行速度比 likes/setLikedShops 快。

我认为问题在于 likes/setLikesShops 过程在没有获取用户信息的情况下继续进行,但我没有得到解决方案。

如何确保先获取 user_id 再获取收藏夹?

// plugins/firebase.js
firebase.auth().setPersistence(firebase.auth.Auth.Persistence.LOCAL)
// middleware/auth.js
export default function(store) 
    store.dispatch('auth/onAuth')

// pages/index.vue
async mounted() 
    await this.$store.dispatch('shop/getShops')
    await this.$store.dispatch('likes/getLikes')
    return

// store/auth.js
export const state = () => (
    userId: '',
    userUid: '',
    userEmail: '',
    loggedIn: false,
)

export const mutations = 
    loginStatusChange(state, status) 
        state.loggedIn = status
    ,
    setUserUid(state, userUid) 
        state.userUid = userUid
    ,
    setUserEmail(state, userEmail) 
        state.userEmail = userEmail
    ,
    setUserId(state, userId) 
        state.userId = userId
    


export const actions = 
    login( commit, dispatch , payload) 
        firebase
            .auth()
            .signInWithEmailAndPassword(payload.email, payload.password)
        .then(async (result) => 
            const user = result.user
            commit('loginStatusChange', true)
            console.log('Login was successful')
            commit('setUserUid', user.uid)
            commit('setUserEmail', user.email)
            await dispatch('getUserInfo', user.uid)
            await this.$router.push('/')
        )
        .catch((error) => 
            const errorCode = error.code
            console.log('error: ' + errorCode)
        )
    ,
    onAuth( commit, dispatch ) 
        firebase.auth().onAuthStateChanged(async user => 
            user = user ? user : 
            commit('setUserUid', user.uid)
            commit('setUserEmail', user.email)
            commit('loginStatusChange', user.uid ? true : false)
            await dispatch('getUserInfo', user.uid)
        )
    ,
    async getUserInfo(commit, uid) 
        const data = await axios.get(
            'http://localhost:8000/api/v1/users/'
            + uid
        )
        commit('setUserId', data.data.id)
    


export const getters = 
    isAuthenticated(state) 
        return state.loggedIn != false
    


// store/likes.js
export const state = () => (
    
        likedShops: [],
        likedShopIds: []
    
)

export const mutations = 
    setLikedShops(state, shops) 
        state.likedShops.push(...shops)
    ,
    setLikedShopIds(state) 
        state.likedShopIds = state.likedShops.map(obj => obj.shop_id)
        console.log('likedShopIds: ' + state.likedShopIds)
    


export const actions = 
    async getLikes( rootState, commit ) 
        const userUid = await rootState.auth.userUid
        const user = await axios.get(
            `$process.env.baseUrl/users/$userUid`
        )
        const userId = await user.data.id
        const result = await axios.get(
            `$process.env.baseUrl/likes/$userId`
        )
        await commit('setLikedShops', result.data)
        await commit('setLikedShopIds')
    ,


export const getters = 
    getLikedShops: (state) => 
        return state.likedShops
    ,
    getLikedShopIds: (state) => 
        return state.likedShopIds
    

【问题讨论】:

嗨,我的回答有帮助吗? 【参考方案1】:

如果您想确保中间件在继续之前完全准备好,您也应该await store.dispatch('auth/onAuth')

建议使用async/await 而不是.then(已弃用),因此请尝试在任何地方使用它,不要在它们之间进行奇怪的混合。

另外,即使您的 login 方法应该工作正常,我仍然会尝试将所有 commit 包装到一个操作中,以便您确定它们已正确执行,跟随您等待的调度流程。

您可能应该配置您的axios instance globally,使用runtimeConfig env variables 并从likes.js 文件中删除您的getter,因为您在没有任何修改/格式化/排序/等的情况下访问它们(在此处使用常规状态)。

【讨论】:

以上是关于如何用 Nuxt 控制 Vuex 的执行顺序的主要内容,如果未能解决你的问题,请参考以下文章

如何用python按顺序获取一个线条组成的图形的点坐标

Java类的各种成员初始化顺序如:父子类继承时的静态代码块,普通代码块,静态方法,构造方法,等先后顺

如何用 jest 测试 nuxt?

如何用参数控制执行不同的sql语句(在线等答案

在从本地存储恢复 Vuex Store 之前执行的中间件

如何用Python交互执行shell脚本