美文网首页web前端
vue3嵌套路由(后台管理系统)

vue3嵌套路由(后台管理系统)

作者: 姜治宇 | 来源:发表于2022-11-07 11:34 被阅读0次

    如何设计一个后台管理系统的路由呢?这里就需要使用到嵌套路由。

    嵌套路由

    带children的嵌套路由可以有页面,也可以没有。这里带页面的是home页,因为要设计后台框架结构,没有的话就会指向默认页面,参考任务管理这一项。
    router.ts:

    import { createRouter, createWebHistory,  RouterView } from "vue-router"
    const routes = [
      {
        path: "/login",
        name: "login",
        meta: {
          title: "登录"
        },
        component: () => import("@/pages/login/index.vue")
      },
      {
        path: "/",
        name: "index",
        meta: {
          title: "首页"
        },
        component: () => import("@/pages/home/index.vue"),//页面实现后台结构
        children: [ //子路由
          {
            path: "",
            redirect: "terrain_slice"
          },
          {
            path: "terrain_slice",
            name: "terrain_slice",
            meta: {
              title: "地形切片"
            },
            component: () => import("@/pages/TerrainSlice/index.vue")
          },
          {
            path: "image_slice",
            name: "image_slice",
            meta: {
              title: "影像切片"
            },
            component: () => import("@/pages/ImageSlice/index.vue")
          },
          {
            path: "task_manage",
            name: "task",
            meta: {
              title: "任务管理"
            },
            component: RouterView, //无页面
            children: [ //子路由
              {
                path: "",
                name: "task_manage",
                meta: {
                  title: "任务管理"
                },
                component: () => import("@/pages/TaskManage/index.vue")
              },
              {
                path: "task_details",
                name: "task_details",
                meta: {
                  title: "任务详情"
                },
                component: () => import("@/pages/TaskManage/TaskDetails/index.vue")
              }
            ]
          }
        ]
      }
    ]
    
    
    const ssoResult = () => {
      return new Promise((resolve) => {
        setTimeout(()=>{
            resolve({accessToken:'123456'})
        },200)
      })
    }
    
    const router = createRouter({
      routes,
      history: createWebHistory()
    })
    router.beforeEach(async (to, from, next) => {
      console.log(to.path)
      if (to.path.indexOf("login") === -1) { //如果是访问首页,需要检测token
       
        const token = localStorage.getItem("token")
    
        if (token) {
          next()
        } else {
          let result: any = await ssoResult() //异步获取token
    
          if (result && result.accessToken) {
            localStorage.setItem("token", result.accessToken)
            next()
          } else {
            next("/login")
          }
        }
      } else {
        next()
      }
    })
    export default router
    
    

    App.vue:

    <template>
      <el-config-provider :locale="locale">
        <div class="app">
          <RouterView />
        </div>
      </el-config-provider>
    </template>
    
    <script setup lang="ts">
    import zhCn from "element-plus/lib/locale/lang/zh-cn"
    import { RouterView } from "vue-router"
    const locale = zhCn
    </script>
    

    main.js:

    import { createApp } from "vue"
    import microApp from "@micro-zoe/micro-app"
    import "virtual:svg-icons-register"
    import router from "@/router"
    import store from "@/store"
    import SvgIcon from "@/components/SvgIcon/index.vue"
    import App from "./App.vue"
    import "@/styles/index.scss"
    import handleRouterPermission from "@/utils/permission"
    
    microApp.start()
    
    const app = createApp(App)
    app.use(router)
    app.use(store)
    app.component("SvgIcon", SvgIcon)
    
    // 处理权限登录逻辑
    handleRouterPermission(router)
    
    app.mount("#app")
    

    home/index.vue

    <template>
        <el-config-provider :locale="locale">
          <div class="content">
            <Header /><!--顶部-->
            <div class="app-content">
              <Sidebar /> <!--侧边栏-->
              <div class="app-container">
                <RouterView /> <!--主体部分-->
              </div>
            </div>
          </div>
        </el-config-provider>
      </template>
      
      <script setup lang="ts">
      import zhCn from "element-plus/lib/locale/lang/zh-cn"
      import { RouterView } from "vue-router"
      import Header from "@/components/Header/index.vue"
      import Sidebar from "@/components/Sidebar/index.vue"
      const locale = zhCn
      </script>
      
      <style lang="scss" scoped>
      </style>
    

    侧边栏sidebar.vue:

    <template>
      <div class="sidebar">
        <router-link class="siderbar-item" v-for="p in menuList" :key="p.path" :to="{ name: p.path }">
          <span class="sidervar-item-title">
            {{ p.name }}
          </span>
        </router-link>
      </div>
    </template>
    
    <script setup lang="ts">
    import { RouterLink } from "vue-router"
    const menuList = [
      {
        name: "地形切片",
        path: "terrain_slice",
        icon: "icon-dx"
      },
      {
        name: "影像切片",
        path: "image_slice",
        icon: "icon-yx"
      },
      {
        name: "任务管理",
        path: "task_manage",
        icon: "icon-rwgl"
      }]
    </script>
    

    动态组件

    动态组件就是根据参数的不同,显示不同的组件。比如任务管理是一个列表页,而列表项对应的详情页面都不同,这样可以设计一个统一的detail页面,再根据参数的不同显示不同组件的信息。
    detail/index.vue:

    <template>
      <div class="common-container no-scrollbar">
        <component :is="chooseComponent"  />
      </div>
    </template>
    <script setup lang="ts">
    import { useRoute } from "vue-router"
    import { onMounted, onBeforeUnmount, reactive, ref, computed } from "vue"
    import { ElMessage } from "element-plus"
    import ImageDetails from "./ImageDetails/index.vue"
    import TerrainDetails from "./TerrainDetails/index.vue"
    import PointCloudSliceDetails from "./PointCloudSlice/index.vue"
    const route = useRoute()
    const tasktype = ref<number>(Number(route.query.tasktype)) //接收动态参数
    const chooseComponent = computed<any>(() => {  //计算属性,决定显示哪个组件
     
      switch (tasktype.value) {
        case 1:
          return TerrainDetails
        case 2:
          return ImageDetails
        case 3:
          return PointCloudSliceDetails
        case 4:
          return InstanceModelSliceDetails
        case 5:
          return TiltModelSliceDetails
        case 6:
          return GeneralModelSliceDetails
    
      }
    })
    </script>
    

    相关文章

      网友评论

        本文标题:vue3嵌套路由(后台管理系统)

        本文链接:https://www.haomeiwen.com/subject/vadwtdtx.html