有时候做一个后台管理系统实现动态路由,动态即不是写死的,是可变的。我们可以根据自己不同的需求加载不同的路由,做到不同的实现及页面的渲染。动态的路由存储可分为两种,第一种是前端用自己编写,第二种是后端将路由字段发送到前端,前端通过接口获得的。

本文就模拟下后台路由配置,并编写动态路由配置的方法


  1.  创建api文件 => 再创建menu.js编写路由信息,使用定时器来模拟后台返回的延迟。

export const getMenu = () => {
    return new Promise((resolve) => {
        setTimeout(() => {
            /**
             * @type {import('vue-router').RouteConfig}
             */
            const routes = [
                {
                    path: '/home',
                    name: 'home',
                    component: () => import('@/views/home'),
                    meta: { title: '首页', icon: 's-home' }
                },
                {
                    path: '/user',
                    name: 'user',
                    component: () => import('@/views/user'),
                    meta: { title: '用户管理', icon: 'user' }
                },
                {
                    path: '/mall',
                    name: 'mall',
                    component: () => import('@/views/mall'),
                    meta: { title: '商品管理', icon: 'video-play' }
                },
                {
                    path: '/order',
                    name: 'order',
                    component: () => import('@/views/order'),
                    meta: { title: '订单管理', icon: 'location' },
                    children: [
                        {
                            path: '/pageOne',
                            name: 'pageOne',
                            component: () => import('@/views/order/components/pageOne'),
                            meta: { title: '订单详情', icon: 'setting' },
                        },
                        {
                            path: '/pageTwo',
                            name: 'pageTwo',
                            component: () => import('@/views/order/components/pageTwo'),
                            meta: { title: '订单列表', icon: 'eleme' },
                        },
                    ]
                },
            ]
            resolve(routes)
        })
    })
}

  2.  在路由router的index.js下用vuex来获取路由,将数据传递到vuex,这样可以复用,菜单导航、面包屑可以复用:内容如下

import { getMenu } from '@/api/mockServeDate/menu'
import Vue from 'vue'
import VueRouter from 'vue-router'
// 引入vuex仓库
import store from '@/store'
Vue.use(VueRouter)

const router = new VueRouter({
    mode: 'hash',
    routes: []
})

// 定义变量接收api的路由数据
let mRoutes
router.beforeEach(async (to, form, next) => {
    if (!mRoutes) {
        mRoutes = await getMenu()
        // 向仓库发送api的路由数据
        store.commit('setMenu', mRoutes)
        router.addRoute({
            path: '/',
            name: 'Main',
            component: () => import('@/views/Main'),
            children: mRoutes
        })
        router.addRoute({
            path: '/*',
            redirect: 'Main'
        })
        console.log(mRoutes, router.getRoutes(), '打印路由1')
        next({ ...to })
    } else {
        console.log(mRoutes, '打印路由2')
    }
    next()
})

export default router

  3.  store的index.js获取路由:内容如下

/**
 * @type {import('vuex').StoreOptions<{
 *  menu: import('vue-router').RouteConfig[]
 * }>}
 */

export default {
    state: {
        menu: [],
    },
    mutations: {
        setMenu(state, meun) {
            state.menu = meun
        },
    },
    getters: {
        getMenu(state) {
            return state.menu
        }
    }
}

到这里,动态路由就已经配置好了,总体来说不是很难,但只要理清了思路,写起代码就会很清晰。


这是CommonAside的代码如下:

<template>
  <div>
    <el-menu
      class="el-menu-vertical-demo"
      :collapse="isCollapse"
      background-color="#545c64"
      text-color="#fff"
      active-text-color="#ffd04b"
    >
      <h4>通用后台管理系统</h4>
      // 在子组件配置路由
      <AsideItems :menu="menu" />
    </el-menu>
  </div>
</template>

<script>
import AsideItems from "./components/AsideItems";
export default {
  name: "CommonAside",
  components: {
    AsideItems,
  },
  data() {
    return {
      menu: [],
    };
  },
  mounted() {
    const mRoutes = this.$store.state.menu.menu;
    this.menu = mRoutes;
  },
};
</script>

这是子组件AsideItems的代码如下: 递归调用

<template>
  <div>
    <!-- 一定要加template遍历  递归调用 不然无效 -->
    <template v-for="(item, i) in menu">
      <!-- 判断没有子路由的 -->
      <el-menu-item
        v-if="!item.children"
        :key="i"
        :index="item.name"
        @click="$router.push({ name: item.name })"
      >
        <i :class="'el-icon-' + item.meta.icon"></i>
        <span slot="title">{{ item.meta.title }}</span>
      </el-menu-item>
      <!-- 有子路由的导航 -->
      <el-submenu v-else :key="i" :index="item.name">
        <template slot="title">
          <i :class="'el-icon-' + item.meta.icon"></i>
          <span slot="title">{{ item.meta.title }}</span>
        </template>
        <!-- 子路由 -->
        <aside-item :menu="item.children"></aside-item>
      </el-submenu>
    </template>
  </div>
</template>

<script>
export default {
  name: "AsideItem",
  props: {
    menu: { type: Array },
  },
};
</script>

     效果如图所示:

        到这里就可以实现动态显示路由了,模拟给的后端接口数据去编写路由的获取 渲染。第一次总结,可能不太好,希望对看文章的你有帮助!

Logo

前往低代码交流专区

更多推荐