【问题标题】:Wait for axios API call in vuex to finish before continuing vue-router guard在继续 vue-router 保护之前等待 vuex 中的 axios API 调用完成
【发布时间】:2021-07-04 07:33:58
【问题描述】:

我有一个 django-rest-axios-vuejs 应用程序堆栈,我正在尝试在 vue-router 中做一些事情。

vue-routerbeforeEach 守卫中,我正在验证权限,这是通过检查 vuex 商店中名为 me 的对象中的内容来完成的。一切正常,除非我刷新页面。

确实刷新页面也会清除 vuex 存储,我的 beforeEach 尝试检查存储中的 me 对象,该对象是空的。

因此,如果该 me 对象不在商店中,我想从 API 中获取它。 问题是它需要“一些时间”并且hasPermission() 方法在 API 调用完成之前执行。

所以我尝试在我的 API 调用之前放置一个 await 关键字,但它不起作用。

我的beforeEach 后卫:

router.beforeEach(async (to, from, next) => {
  const isLoggedIn = getIsLoggedIn()
  handleLoggedInStatus(isLoggedIn)
  if (to.meta.requiresAuth) {
    if (isLoggedIn) {
      if (to.meta.permission) {
        if (!store.state.me) await store.dispatch('FETCH_ME')
        hasPermission(to.meta.permission) ? next() : next({ name: 'HomePage' })
      } else {
        next()
      }
    } else {
      next({ name: 'LoginForm' })
    }
  } else {
    next()
  }
})

我在商店的行动:

actions: {
    FETCH_ME: (state) => {
      http
        .get('base/users/me/')
        .then(response => {
          state.me = response.data
        })
        .catch(error => {
          console.log(error)
        })
    }
  }

我发现让它等待的唯一方法是执行以下操作:

function sleep (ms) {
  return new Promise(resolve => setTimeout(resolve, ms))
}

router.beforeEach(async (to, from, next) => {
  const isLoggedIn = getIsLoggedIn()
  handleLoggedInStatus(isLoggedIn)
  if (to.meta.requiresAuth) {
    if (isLoggedIn) {
      if (to.meta.permission) {
        if (!store.state.me) {
          store.dispatch('FETCH_ME')
          await sleep(2000)
        }
        hasPermission(to.meta.permission) ? next() : next({ name: 'HomePage' })
      } else {
        next()
      }
    } else {
      next({ name: 'LoginForm' })
    }
  } else {
    next()
  }
})

使用一点sleep() 方法让它等待“随机”(2 秒)时间。

我对@9​​87654335@ await 的用法有点陌生,所以.. 要使await store.dispatch('FETCH_ME') 工作,我缺少什么?

提前致谢:)

【问题讨论】:

    标签: javascript vue.js asynchronous vuex vue-router


    【解决方案1】:

    我有一个类似逻辑的宠物项目。我没有使用元

    async beforeEnter(to, from, next) {
       await store.dispatch('getUser')
       if (store.getters.user) return next()
        next('/login')
    }
    

    逻辑如下。如果用户已登录,则浏览器中有一个 cookie,它与 store.dispatch 一起发送。而如果token有效,则后端返回用户,即如果getter返回用户,则用户已登录。我想你的逻辑应该是一样的

    【讨论】:

      【解决方案2】:

      我终于找到了这个我以前没见过的LINK...

      这让我可以像这样重写我的FETCH_ME 操作:

      FETCH_ME ({ commit }) {
        return new Promise((resolve, reject) => {
          http
           .get('base/users/me/')
           .then(response => {
             commit('SET_ME', response.data)
             resolve()
           })
           .catch(error => {
             console.log(error)
             reject(error)
           })
         })
      }
      

      SET_ME 是我已经拥有的突变:

      SET_ME: (state, user) => {
        state.me = user
      },
      

      这最终适用于我的情况,在 router.beforeEach 守卫中执行此操作:

      if (!store.state.me) await store.dispatch('FETCH_ME') 有效地等待 dispatch 操作完成。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-15
        • 2015-09-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多