Home > front end >  Dynamic router VueJS
Dynamic router VueJS

Time:02-05

I'm trying to create routes dynamically but unfortunately I'm not succeeding and it's not possible with Vuejs 3

import { createRouter, createWebHistory } from "vue-router";
import TopMenu from "../layouts/top-menu/Main.vue";
import hosts from '@/utils/hosts';
import Login from "../views/admin/login/Main.vue";
import Home from "../views/admin/home/Main.vue";
import Sair from "../views/admin/sair/Main.vue";

import { listaPaginas } from "@/composable/arthysis/paginas";

let routes = [];
var lstRoutes = [];

async function loadPage() {
  var { statuscode, message, data } = await searchPage();

    lstRoutes.push({
        path: `${hosts.app}`   "/home",
        name: "admManHome",
        component: Home,    
      });

    for (var i = 0; i < data.length; i  ) {
      lstRoutes.push({
        path: `${hosts.app}/${data[i].path}`,
        name: data[i].name_page,
        component: () => import('../views/'  data[i].path  '/'  data[i].name_page  '.vue')
      });
  
    }

}

await loadPage();

routes = [
  {
    path: `${hosts.app}/`,
    name: "admManLogin",
    component: Login,

  },
  { 
    component: TopMenu,
    children: lstRoutes    
  }
];

const router = createRouter({
  history: createWebHistory(),
  routes,
  scrollBehavior(to, from, savedPosition) {
    return savedPosition || { left: 0, top: 0 };
  },
});

export default router;

it is giving this error

vue-router.mjs:1486 Uncaught TypeError: Cannot read properties of undefined (reading 'forEach') at createRouterMatcher (vue-router.mjs:1486:12) at createRouter (vue-router.mjs:2942:21) at index.js?t=1675540466219:137:16

I tried to create a function to import the component but it also gives the same error

CodePudding user response:

main.js

import { createApp, ref } from "vue";
import { createPinia, defineStore } from "pinia";
import App from "./App.vue";
import router from "./router";
import globalComponents from "./global-components";
import utils from "./utils";
import "./assets/css/app.css";
import hosts from '@/utils/hosts';
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';

const pinia = createPinia();

pinia.use(piniaPluginPersistedstate);

const app = createApp(App).use(router).use(pinia);

globalComponents(app);
utils(app);

app.mount("#app");

router.beforeEach(async (to, from, next) => {
     
     
     if ((localStorage.getItem("token") == undefined || localStorage.getItem("token") == null) && to.name != 'admManLogin') {

          localStorage.removeItem("token");
          localStorage.removeItem("dataExptoken");
          localStorage.removeItem("loja");

          next({ path: `${hosts.app}/` })
     }

     if (localStorage.getItem("dataExptoken") != undefined && Date.now() > localStorage.getItem("dataExptoken")) {

          localStorage.removeItem("token");
          localStorage.removeItem("dataExptoken");
          localStorage.removeItem("loja");

          next({ path: `${hosts.app}/` })
     }
     

     next()
})

CodePudding user response:

The problem should be caused by the fact that you are trying to access the route array before it is built, you should access it when you are sure it is complete. One solution to fix this could be to wrap the on createRouter code in an async function.

I tried to write you a possible version of the new code:

import { createRouter, createWebHistory } from "vue-router";
import TopMenu from "../layouts/top-menu/Main.vue";
import hosts from '@/utils/hosts';
import Login from "../views/admin/login/Main.vue";
import Home from "../views/admin/home/Main.vue";
import Sair from "../views/admin/sair/Main.vue";

import { listaPaginas } from "@/composable/arthysis/paginas";

let routes = [];
var lstRoutes = [];

async function loadPage() {
  var { statuscode, message, data } = await searchPage();

    lstRoutes.push({
        path: `${hosts.app}`   "/home",
        name: "admManHome",
        component: Home,    
      });

    for (var i = 0; i < data.length; i  ) {
      lstRoutes.push({
        path: `${hosts.app}/${data[i].path}`,
        name: data[i].name_page,
        component: () => import('../views/'  data[i].path  '/'  data[i].name_page  '.vue')
      });
  
    }

}

async function createRouterInstance() {
  await loadPage();

  routes = [
    {
      path: `${hosts.app}/`,
      name: "admManLogin",
      component: Login,

    },
    { 
      component: TopMenu,
      children: lstRoutes    
    }
  ];

  const router = createRouter({
    history: createWebHistory(),
    routes,
    scrollBehavior(to, from, savedPosition) {
      return savedPosition || { left: 0, top: 0 };
    },
  });

  return router;
}

export default createRouterInstance();

EDIT:

to solve the second problem you posted, the error could be caused by the "next" function being called multiple times in the beforeEach guard. try adding a return statement after each next.

router.beforeEach(async (to, from, next) => {
  if ((localStorage.getItem("token") == undefined || localStorage.getItem("token") == null) && to.name != 'admManLogin') {
    localStorage.removeItem("token");
    localStorage.removeItem("dataExptoken");
    localStorage.removeItem("loja");
    next({ path: `${hosts.app}/` });
    return;
  }

  if (localStorage.getItem("dataExptoken") != undefined && Date.now() > localStorage.getItem("dataExptoken")) {
    localStorage.removeItem("token");
    localStorage.removeItem("dataExptoken");
    localStorage.removeItem("loja");
    next({ path: `${hosts.app}/` });
    return;
  }

  next();
});
  • Related