【问题标题】:Vue router guard triplicating navigationVue路由器守卫三重导航
【发布时间】:2021-06-01 12:24:59
【问题描述】:

我有一个路由器守卫beforeEach 路由来观察是否有用户通过身份验证:

import Vue from "vue";
import VueRouter from "vue-router"
import Login from "../views/Login.vue"
import Home from "../components/Home.vue"
import Register from "../views/Register.vue"
import Dashboard from "../views/Dashboard.vue"
import Pricing from "../components/Pricing.vue"
import Invoices from "../components/Invoices.vue"
import { FirebaseAuth } from "../firebase/firebase"

Vue.use(VueRouter);

const routes = [
  {
    path: "*",
    redirect: "/login",
  },
  {
    path: "/dashboard",
    name: "dashboard",
    component: Dashboard,
    children: [
      {
        path: "home",
        name: "home",
        component: Home,
      },
      {
        path: "pricing",
        name: "pricing",
        component: Pricing,
      },
      {
        path: "invoices",
        name: "invoices",
        component: Invoices,
      }
    ],
    meta: {
      auth: true,
    },
    redirect: "home"
  },
  {
    path: "/login",
    name: "login",
    component: Login,
  },
  {
    path: "/register",
    name: "register",
    component: Register,
  }
];

const router = new VueRouter({
  mode: "history",
  base: process.env.BASE_URL,
  routes
});


router.beforeEach((to, from, next)=>{
  let user = FirebaseAuth.currentUser;
  let auth = to.matched.some(record => record.meta.auth);
  
  if (auth && !user) {

    next('/login');

  } else if (!auth && user) {

    next('/dashboard/home');

  } else{

    next();

  }
});

export default router;

当我执行logoutslogins 时,出现关于冗余导航的错误,但是,我只是假设我只要抓住this.$router.push('/dashboard/home').catch(err => err); 并在没有console.log 错误的情况下继续前进就可以了。但是在组件created() 上创建警报我注意到事情比我想象的更严重,在created() 上显示警报的组件显示了三遍,因为我有一个恢复项目的获取在created() 上,该函数被触发了 3 次,这显然不是想要的性能。

  async created() {
    alert("created")
    this.credits = await fetchCredits(this.$firestore, this.$auth.currentUser);
    let role = await getCustomClaimRole(this.$auth.currentUser);
    this.subscription = role
      ? role.charAt(0).toUpperCase() + role.slice(1) + " " + "plan"
      : "You haven't subscribed yet";
    this.isLoading();
  },

fetchCredits()里面是console.log触发3次

export const fetchCredits = async function (firestore, currentUser) {
    // firestore collection of customers
    const db = firestore.collection("customers");
    /**
     * Let's fetch the credits from the user:
     */
    const credits = (await db.doc(currentUser.uid).get()).data();
    if (credits !== "undefined") {
        console.log(credits);
        return credits.credits
    } else {
        return 0;
    }
}

我认为问题出在导航守卫上,但是,如果我错了,请纠正我,但是如何解决这个问题?

【问题讨论】:

    标签: vue.js vue-component vue-router


    【解决方案1】:

    我认为这与您的路由器路径有关:

      {
        path: "*",
        redirect: "/login",
      },
    

    我曾多次使用过 Vue Router,但由于之前没有使用过通配符,所以我构建了一个简化的 Vue 2 CLI 测试应用程序。

    我的路由器:

    import Vue from 'vue'
    import VueRouter from 'vue-router'
    
    Vue.use(VueRouter)
    
    import Home from '@/components/stackoverflow/router-wildcard-match/Home'
    import RouteOne from '@/components/stackoverflow/router-wildcard-match/RouteOne'
    import RouteTwo from '@/components/stackoverflow/router-wildcard-match/RouteTwo'
    import WildCard from '@/components/stackoverflow/router-wildcard-match/WildCard'
    
    const routes = [
      {
        path: '/*',
        name: 'wildcard',
        component: WildCard
      },
      {
        path: '/home',
        name: 'home',
        component: Home,
      },
      {
        path: '/routeone',
        name: 'routeOne',
        component: RouteOne,
      },
      {
        path: '/routetwo',
        name: 'routeTwo',
        component: RouteTwo,
      },
    ]
    
    export default new VueRouter({
      mode: 'history',
      base: process.env.BASE_URL,
      routes
    })
    

    还有我以编程方式路由的导航栏组件:

    <template>
      <div class="navbar-sandbox">
        <nav class="navbar navbar-expand-md navbar-light bg-light">
          <ul class="navbar-nav mr-auto">
            <li class="nav-item active">
              <a class="nav-link" href="#" @click.prevent="navigate('home')">Home</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#" @click.prevent="navigate('routeone')">RouteOne</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#" @click.prevent="navigate('routetwo')">RouteTwo</a>
            </li>
          </ul>
        </nav>
      </div>
    </template>
    
    <script>
      export default {
        data() {
          return {
            //currentRoute: 'home',
            currentPath: 'home'
          }
        },
        methods: {
          // NOTE: Using route names work regardless of having wildcard path
          // navigate(route) {
          //   if (route !== this.currentRoute) {
          //     this.currentRoute = route;
          //     this.$router.push({ name: route });
          //   }
          // },
          navigate(path) {
            if (path !== this.currentPath) {
              this.currentPath = path;
              this.$router.push({ path: path });
            }
          }
        }
      }
    </script>
    

    正如您在我的代码 cmets 中看到的,当我通过路由名称以编程方式路由时,即使有通配符路径,它也可以工作,但是当我通过实际路由路径进行路由时,路由都被通配符拦截。

    我的通配符路径和你的有点不同,/* vs *

    【讨论】:

      猜你喜欢
      • 2019-10-21
      • 2021-10-04
      • 1970-01-01
      • 1970-01-01
      • 2017-10-01
      • 1970-01-01
      • 2018-07-14
      • 2020-02-11
      • 2020-11-23
      相关资源
      最近更新 更多