繁体   English   中英

等待 vuex 中的 axios API 调用完成,然后继续 vue-router 保护

[英]Wait for axios API call in vuex to finish before continuing vue-router guard

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

在每个守卫之前的vue-router中,我正在验证权限,它是通过检查在beforeEach商店中调用me的 object 中的某些内容来完成的。 一切正常,除非我刷新页面。

确实刷新页面也清除了 vuex 商店,我的beforeEach尝试从商店中检查me object 是空的。

因此,如果商店中没有,我想从 API 获取这个me object。 问题是它需要“一些时间”并且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 秒)时间。

我对async await的使用有点陌生所以..让await store.dispatch('FETCH_ME')工作我缺少什么?

提前致谢:)

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

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

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

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

这让我可以像这样重写我的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操作完成。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM