3

In a real-world Vue application, the router can easily get to several hundred line long so I split the router.js into separate (component) route files and import them into an index.js However, while doing so, I broke the beforEach function and I cannot figure out how to use the authentication guard with the refactored code.

The below implementation use of beforeEach throws:

Uncaught TypeError: routes.beforeEach is not a function

Any help with examples would be greatly appreciated!

My Routes index.js:

import Vue from 'vue';
import Router from "vue-router";
import firebase from 'firebase'

// BASE ROUTES
import {
  . . .
  aBunch,
  ofRoutes,
  . . .
} from '@/routers/base'

// INVENTORY ROUTERS
import {
  . . .
  aBunch,
  more,
  routes,
  . . .
} from '@/routers/inventory'

Vue.use(Router);

const baseRoute = [
  {
    path: '*',
    redirect: '/login'
  },
  {
    path: '/',
    redirect: '/login'
  },
  {
    path: '/login',
    name: 'login',
    component: load('Login'),
    meta: { transitionName: 'slide' },
  },
  {
    path: '/sign-up',
    name: 'sign up',
    component: load('Signup'),
    meta: { transitionName: 'slide' },
  },
]

const routes = baseRoute.concat(
  . . .
  concat,
  aBunch,
  ofRoutes,
  . . .
  );

function load (component) {
  return () => import(
    /* webpackChunkName: "[request]" */
    `@/views/${component}.vue`
  )
}

routes.beforeEach((to, from, next) => {
  let currentUser = firebase.auth().currentUser
  let requiresAuth = to.matched.some(record => record.meta.requiresAuth)

  if (requiresAuth && !currentUser) next('login')
  else if (!requiresAuth && currentUser) next('dashboard')
  else next()
})

export default new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  routes,
});

1 Answer 1

4

beforeEach is on router.

let router =  new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  routes,
});

router.beforeEach((to, from, next) => {
  let currentUser = firebase.auth().currentUser;
  let requiresAuth = to.matched.some(record => record.meta.requiresAuth);

  if (requiresAuth && !currentUser) next('login');
  else if (!requiresAuth && currentUser) next('dashboard');
  else next();
});

export default router;

if you also wanted to put beforeEach in its own file, you could import the router you construct into another file and call it there

import Router from "@/router";

export default () => {
  Router.beforeEach( ... );
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thnx, I had thought I had tried that before so I attempted it again because I wasn't sure. Unfortunately that throws the an undefined error. Also, I planned on moving the guards into a separate file but I usually do that once I have things working so I'm not chasing my tail (LOL).
Correction! Your answered is correct; I had I type-o when I refactored the code. Thnx!
In vue 4.x, no need to write to.matched.some if the meta fields don't have duplicate values. "but Vue Router also provides you a route.meta that is a non-recursive merge of all meta fields from parent to child"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.