element-admin-templateテンプレートプロジェクト動的追加ルーティング


最近のプロジェクトでは、魯有が動的に取得し、バックエンドからデータを返して処理する必要がある.私のプロジェクトテンプレートはelement-damin-templateに基づいています.公式文書でも紹介されています
https://panjiachen.github.io/vue-element-admin-site/zh/guide/essentials/permission.html#%E9%80%BB%E8%BE%91%E4%BF%AE%E6%94%B9
通常のルーティングは私たち自身がrouter/indexの中で自分で定義したルーティングを、ロード時に処理しないと直接すべてロードされ、バックグラウンドデータは一般的に権限制御が必要です.一般的には、バックグラウンドで私たちのアカウントが示すルートを返す必要があります.私たちが動的にロードします.
まず、これらの権限ルーティング情報を携帯するバックエンドインタフェースが必要です.次に、私たちのrouterにロードする方法を考えます.
  • 我々のrouterルーティングテーブルで我々の共通ルーティングを定義する:
  • import Layout from '@/layout/index'
    import Vue from 'vue'
    import Router from 'vue-router'
    Vue.use(Router)
    
    export const constantRoutes = [
    
        //    
        {
            path: '/login',
            component: (resolve) => require(['@/views/login/index'], resolve),
            hidden: true
        },
    
    
    
        //   
        {
            path: '/',
            component: Layout,
            redirect: '/dashboard',
            children: [{
                path: 'dashboard',
                name: 'Dashboard',
                component: (resolve) => require(['@/views/dashboard/index'], resolve),
                meta: { title: '  ', affix: true }
            }]
        },
        //    
        {
            path: '/404',
            component: (resolve) => require(['@/views/404'], resolve),
            hidden: true
        },
    ]
    
    const createRouter = () => new Router({
        mode: 'history',
        scrollBehavior: () => ({ y: 0 }),
        routes: constantRoutes
    })
    
    const router = createRouter()
    
    
    export function resetRouter() {
        const newRouter = createRouter()
        router.matcher = newRouter.matcher 
    
    }
    router.$addRoutes = function(params) {
        router.matcher = new Router({ mode: 'history' }).matcher;
        router.addRoutes(params)
    }
    export default router
    
  • は共通ルーティングを定義し、次はバックエンドから戻ってきたルーティングテーブルを取得し、storeのpermissionに入る.jsファイル
  • import { getMenus } from '@/api/setUp/menu';
    import Layout from '@/layout/index';
    import vue from '@/main';
    import { constantRoutes } from '@/router';
    const permission = {
    
        state: {
            routers: [],
            addRouters: []
        },
        mutations: {
            SET_ROUTES: (state, router) => {
                state.addRouters = router;
                state.routers = constantRoutes.concat(router);
            }
        },
        actions: {
            //     
            GenerateRoutes({ commit }) {
                return new Promise(resolve => {
                    // isLogin: 0           isLogin: 1             
                    let data = {
                            isLogin: 1
                        }
                        //           
                    getMenus(data).then(res => {
                        //                  
                        for (var i = 0; i < res.data.length; i++) {
                            res.data[i].children = []
                        }
                        let routes = vue.handleTree(res.data, "id");
    
                        //    getAsyncRoutes              
                        let accessedRoutes = getAsyncRoutes(routes)
                            //  404
                        accessedRoutes.push({ path: '*', redirect: '/404', hidden: true })
                            //        
                        commit('SET_ROUTES', accessedRoutes)
                            //        
                        resolve(permission.state.routers)
                    })
                })
            }
        }
    }
    
    /**
     1.           routes     
     2. @param {*} routes
     */
    export function getAsyncRoutes(routes) {
        const res = []
        routes.forEach(item => {
            const newItem = {}
            if (item.component) {
                if (item.component === 'layout') {
                    newItem.component = Layout
                } else {
                    newItem.component = loadView(item.component)
                        //                ,         webpack,    require   OK 
                        // newItem.component = () =>
                        //     import (`@/views/${item.component}`)
                }
            }
            newItem.meta = {
                title: item.name
            }
            newItem.name = item.path
            newItem.path = `/${item.path}`
            if (item.children && item.children.length) {
                newItem.children = getAsyncRoutes(item.children)
            }
            res.push(newItem)
        })
        return res
    }
    export const loadView = (view) => { //      
        return (resolve) => require([`@/views/${view}`], resolve)
    }
    export default permission
    

    このうち、バックエンドから戻ってきたデータは2回処理する必要がありますので、バックエンドのデータフォーマットに合わせて適宜処理すればいいです.3.その後私たちはgetters.js内設定
     permission_routes: state => state.permission.routers
    

    そしてlayoutのsidebar/index.vueのcomputedが導入され、私のプロジェクトのナビゲーションバーが異なるとあまり展示されません.
    ...mapGetters(["permission_routes","sidebar"]),
    

    4.permissionに入ります.jsファイル、このファイルは私たちのルーティングブロックプロファイルです.ここでstoreで設定したGenerateRoutesを呼び出し、routerに追加します.
    import { getToken } from '@/utils/auth' // get token from cookie
    import getPageTitle from '@/utils/get-page-title'
    import { Message } from 'element-ui'
    import NProgress from 'nprogress' // progress bar
    import 'nprogress/nprogress.css' // progress bar style
    import routers from './router'
    import store from './store'
    
    
    NProgress.configure({ showSpinner: false }) // NProgress Configuration
    
    const whiteList = ['/login'] //    
    
    routers.beforeEach(async(to, from, next) => {
        //       
        NProgress.start()
    
        //     
        document.title = getPageTitle(to.meta.title)
            //          
        const hasToken = getToken()
    
        if (hasToken) {
            if (to.path === '/login') {
                next({ path: '/' })
                NProgress.done()
            } else {
                const hasGetUserInfo = store.getters.name
                if (hasGetUserInfo) {
                    next()
                } else {
                    //             !!!!
                    try {
                        //       
                        await store.dispatch('user/getInfo')
                            //   store                
                        const accessRoutes = await store.dispatch('GenerateRoutes')
                            //      $addRoutes             
                        routers.$addRoutes(accessRoutes)
                        routers.options.routes = accessRoutes
                        next({...to, replace: true })
                    } catch (error) {
                        //                
                        await store.dispatch('user/resetToken')
                        Message.error('Has Error')
                        next(`/login?redirect=${to.path}`)
                        NProgress.done()
                    }
                }
            }
        } else {
            /* has no token*/
    
            if (whiteList.indexOf(to.path) !== -1) {
                //          ,    
                next()
            } else {
                //                     .
                next(`/login?redirect=${to.path}`)
                NProgress.done()
            }
        }
    })
    
    routers.afterEach(() => {
        // finish progress bar
        NProgress.done()
    })
    

    このような流れでは基本的に終わります.
    まとめ:1.共通ルーティングを定義します.2.storeでルーティングを取得する方法を設定する(バックエンドで返されるルーティングテーブルデータを取得して処理するのに必要なルーティングフォーマット).ルーティングブロックでstoreを呼び出す方法ルーティングデータを取得しrouterに追加して動的権限制御を実現
    途中で何度も面白い問題に遭遇しましたが、記録を忘れてしまいました.問題があれば、討論を歓迎します.
    覚えがいいのは腐った笔头に及ばないで、早起きの鸟は虫が食べて、アヒルを突きます!!!