【问题标题】:Vue router : run beforeEach after fetching dataVue路由器:在获取数据后运行beforeEach
【发布时间】:2021-08-19 07:50:54
【问题描述】:

我正在开发一个带有身份验证(基于 cookie)的 web 应用程序。当应用程序正在加载(获取全局设置并检查用户是否登录)时,我想显示加载状态。否则可能会显示实际路线。

为了检查用户是否可以访问某个路由,我使用了 vue-router beforeEach 函数

router.beforeEach((to, _, next) => {
  const isLoggedIn = store.getters["auth/isLoggedIn"];

  console.log(`Is user logged in?: ${isLoggedIn}`);

  const requiresAuth = to.matched.some((record) => record.meta.requiresAuth);
  const requiresGuest = to.matched.some(
    (record) => record.meta.redirectIfLoggedIn
  );

  if (requiresAuth && !isLoggedIn) {
    next("/login");
  } else if (requiresGuest && isLoggedIn) {
    next("/");
  } else {
    next();
  }
});

export default router;

获取请求正在App.vue的创建函数中完成

<template>
  <Loader v-if="isLoading" />
  <component v-else :is="this.$route.meta.layout">
    <router-view />
  </component>
</template>

<script>
import Loader from "@/components/general/Loader.vue";

export default {
  data() {
    return {
      isLoading: true,
    };
  },
  components: {
    Loader,
  },
  async created() {
    await this.$store.dispatch("settings/loadSettings");
    await this.$store.dispatch("auth/tryLogin");
    this.isLoading = false;
  },
};
</script>

我面临的问题是 beforeEach 函数在获取完成之前运行,因此isLoggedIn 始终为假。在进入 beforeEach 中间件之前,我可以做些什么来确保获取请求完全完成?

操作的控制台日志:

1) Settings before loading: {"logo_url":null,"background_color":"#089dde","text_color":"#ffffff"} 
2) loading settings 
3) Is user logged in?: false 
4) Settings after loading: {"logo_url":null,"background_color":"#089dde","text_color":"#ffffff"} 
5) User before loading: null 
6) loading user 
7) User after loading: {"id":1,"name":"John Doe","email":"johndoe@company.com"}

我在代码沙盒项目中放置了一些带有虚假提取请求的代码。 https://codesandbox.io/s/elegant-agnesi-399z5

【问题讨论】:

    标签: vue.js authentication vue-router middleware


    【解决方案1】:

    在初始化应用程序之前,Vue 路由器中会发生初始导航。由于商店在 Vue 应用程序实例之外可用,这可以通过在应用程序初始化之前初始化状态来解决。在这种情况下,需要将加载器从 Vue 应用程序移动到 HTML 文件,这也允许尽快显示它。

    或者,可以推迟初始导航,直到应用程序完全初始化。 App 组件可以以任何方式与路由器交互,但应该有一个承诺会阻止 beforeEach 继续进行:

    export let start;
    const startPromise = resolve => { start = resolve };
    
    router.beforeEach(async (to, _, next) => {
      await startPromise;
      ...
    

    await this.$store.dispatch("settings/loadSettings");
    await this.$store.dispatch("auth/tryLogin");
    start();
    

    【讨论】:

      猜你喜欢
      • 2019-05-02
      • 1970-01-01
      • 2022-01-13
      • 1970-01-01
      • 2019-03-27
      • 1970-01-01
      • 2022-09-23
      • 2016-07-07
      • 1970-01-01
      相关资源
      最近更新 更多