vue realizes dynamic routing

Most of the time, the routing of our projects is configured at the front end
But sometimes, in order to carry out comprehensive permission control, the routing table needs to be given in the background and rendered in the front end. No front-end configuration.

Here are the main ideas
1. Communicate the data with the little brother in the background, and give him the routing table data configured at the front end, so that he can understand it

2. We need to process the data ourselves
The component in the route cannot be provided in the background. Here, we only need the background brother to provide data according to the front-end component path provided by us, and we can load it circularly

//view is the data given by the background
return () => import(`@/view/modules/${view}`);

In this way, we get the most important data, namely component.

3. Process the data provided by the background into the routing table we need
4. Add to route

 Router.addRoutes(Routing data)

Let's talk about my implementation process in the project
1. Create a router js
There are some basic routing operations, such as importing packets, because after we get the data, we still have to manually put it into the routing
It will also write menu data that does not need to be provided in the background, such as our test page or login

import Vue from "vue";
import Router from "vue-router";
import AppMain from "@/view/modules/main/index";
Vue.use(Router);
export const _CONSTANTS_ROUTERS =
[
    {
        path: "/login",
        component: () => import("@/view/modules/login/index"),
        hidden: true
    },
    {
        path: "",
        component: AppMain,
        redirect: "/dashboard",
        children: [
            {
                path: "/dashboard",
                component: () => import("@/view/modules/dashboard/index"),
                name: "Dashboard",
                meta: { title: "home page", icon: "dashboard", noCache: true }
            }
        ]
    }
];
export default new Router({
    mode: "history",
    // Solve the bug of white untraceable color block in vue frame page Jump
    scrollBehavior: () => ({ x: 0, y: 0 }),
    // scrollBehavior: () => ({ y: 0 }),
    routes: _CONSTANTS_ROUTERS
});

The basic routing table has been established

2. When do we get the complete routing table data
At this time, we should think of the routing hook function, of course, the router Before each

Router.beforeEach((to, from, next) =>
{
    NProgress.start();
    if (!Token.isEmpty())
    { 
        if (to.path === "/login")
        {
            next({ path: "/" });
            NProgress.done(); 
        }
        else if (to.path === "/404")
        {
            next();
            NProgress.done();
        }
        else
        {
            // Judge whether the current user has pulled the role information
            if (Store.getters.roles.length === 0)
            {
                 //Pull routing data
ACLRepo.listMenuTreeOfCurrentUser().then(response =>
                    {
                        Store.dispatch("generateRoutes", response).then(() =>
                        {
                            // Generate an accessible routing table according to roles permissions
                            Router.addRoutes(Store.getters.addRouters); // Dynamically add accessible routing table
                            next({ ...to, replace: true }); // The hack method ensures that addRoutes has completed, set the replace: true so the navigation will not leave a history record
                        });
                    });
            }
            else
            {
                 next();
            }
        }
    }
    else
    {
       next();
    }
});

3. Route data resealing
generateRoutes

import { _CONSTANTS_ROUTERS } from "@/scripts/router";
import AppMain from "@/view/modules/main/index";
const _PERMISSION = {
    state: {
        routers: _CONSTANTS_ROUTERS,
        addRouters: []
    },
    mutations: {
        setRouters: (state, routers) =>
        {
            state.addRouters = routers;
            //Splicing with existing routing tables
            state.routers = _CONSTANTS_ROUTERS.concat(routers);
        }
    },
    actions: {
        generateRoutes({ commit }, response)
        {
            let asyncRouters = filterAsyncRouter(response);
            asyncRouters.push({ path: "*", redirect: "/404", hidden: true });
            commit("setRouters", asyncRouters);
        }
    }
};

function filterAsyncRouter(routers)
{
    // Traverse the routing string from the background and convert it into a component object
    let accessedRouters = routers.filter(router =>
    {
        if (router.meta)
        {
            // Default icon handling
            router.meta.icon = router.meta.icon ? router.meta.icon : "component";
        }
        if (router.component === "main")
        {
            // Main component special handling
            router.component = AppMain;
        }
        else
        {
            //Processing components - key points
            router.component = loadView(router.component);
        }
        //Existence subset
        if (router.children && router.children.length)
        {
            router.children = filterAsyncRouter(router.children);
        }
        return true;
    });
    return accessedRouters;
}
function loadView(view)
{
    // Route lazy loading
    return 

Posted by vicky57t on Tue, 17 May 2022 16:32:10 +0300