Javascript Vuex商店/导航卫士没有';我第一次不工作

Javascript Vuex商店/导航卫士没有';我第一次不工作,javascript,vue.js,vuex,vue-router,Javascript,Vue.js,Vuex,Vue Router,我在用户的仪表板上有一个导航卫士,需要用户存在才能继续 export default new Router({ routes: [ { path: '/', name: 'home', component: Home }, { path: '/dashboard', name: 'dashboard', component: Dashboard, beforeEnter: (to, f

我在用户的仪表板上有一个导航卫士,需要用户存在才能继续

export default new Router({
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home
    },
    {
      path: '/dashboard',
      name: 'dashboard',
      component: Dashboard,
      beforeEnter: (to, from, next) => {
        const user = JSON.parse(store.state.authenticatedUser)
        if(user) {
          console.log("Route accepted.")
          next()
        } else {
          console.log("Route rejected.")
          next('/')
        }
      }
    }
  ]
})
在我的登录表单上,我发送到obtainToken,它返回令牌和相关用户

<template>
  <v-container>
    <h1 class="display-2">Login</h1>
    <v-form 
      ref="form" 
      v-model="valid" 
      lazy-validation
    >
      <v-col cols="12" md="12">
        <v-row align="center">
          <v-text-field 
            v-model="email" 
            :rules=emailRules 
            label="Email" 
            required 
            dense
          ></v-text-field>
        </v-row>
        <v-row align="center">
          <v-text-field 
            v-model="password"
            label="Password"
            required
            dense
            type="password"
          ></v-text-field>
        </v-row>
      </v-col>
      <v-btn
        @click="login"
      >Login</v-btn>
    </v-form>
  </v-container>
</template>

<script>
export default {
  data: () => ({
    valid: true,
    password: '',
    email: '',
    emailRules: [
      v => !!v || 'Email is required.',
      v => /.+@.+\..+/.test(v) || 'You have entered an invalid email.',
    ],
  }),
  methods: {
    login() {
      this.$store.dispatch('obtainToken', { email: this.email, password: this.password })
      this.$router.push('dashboard')
    }
  }
}
</script>
单击“提交”时,将获得该用户,但该路由将被拒绝,因为当时用户不存在。我必须再次单击
提交
,这将允许用户访问
仪表板
路线

因此,我可以从输出中收集到的是,
$router.push
正在发生,因为
obtainToken
正在发生,所以它们在比赛。第二次登录时,已经有一个用户存在,因此它将继续。我做错了什么


我也尝试过这样做,router.push()也被称为承诺的解决方案

login() {
      this.$store.dispatch('obtainToken', { email: this.email, password: this.password })
      .then(() =>
           this.$router.push('dashboard')
      )
}

调用
dispatch
是异步的

更改路由器时,它尚未定义

因此,在移动另一页之前,需要在
mounted()
中调用dispatch

mounted() {
  this.$store.dispatch('obtainToken', { email: this.email, password: this.password })
},
methods: {
  login() {
    this.$router.push('dashboard')
  }
}

编辑:您需要在
obtainToken
中返回
promise
,如下所示

obtainToken(random, payload) {
  ...
  return api.post(this.state.endpoints.obtainToken, data) // just add `return`
  ...
}

问题似乎出现在
登录
方法中

login() {
      this.$store.dispatch('obtainToken', { email: this.email, password: this.password })
      this.$router.push('dashboard')
}
将同时运行两个呼叫。试图在获取令牌调用结果之前导航用户

login() {
      this.$store.dispatch('obtainToken', { email: this.email, password: this.password })
      .then(() =>
           this.$router.push('dashboard')
      )
}

一旦令牌存在,就可以在导航到仪表板时从状态中获取它。

这意味着在装载登录表单时我正在调用obtainToken,这将导致不必要的api调用。电子邮件和密码在用户提供之前是不存在的,只有在用户添加并提交电子邮件和密码时才能调用obtainToken。不过,异步调度是有帮助的。使用承诺或等待也是我最初的假设,但不幸的是产生了同样的结果。第一条路线被拒绝,但第二条路线通过。你能给我看一下
obtainToken
?它应该返回
promise
(可能正在获取)。请参考此链接。
login() {
      this.$store.dispatch('obtainToken', { email: this.email, password: this.password })
      this.$router.push('dashboard')
}
login() {
      this.$store.dispatch('obtainToken', { email: this.email, password: this.password })
      .then(() =>
           this.$router.push('dashboard')
      )
}