安装

image-20230307232555061

侧边栏的动态路由

完整的Home.vue 文件如下:

<template>
  <div class="home">
    <el-container>
      <el-header>
        <el-row :gutter="20">
          <el-col :span="4"
            ><img src="../assets/logo.png" alt="" class="logo"
          /></el-col>
          <el-col :span="16"><h2>后台管理系统</h2></el-col>
          <el-col :span="4" ><a class="quit-login" @click="delToken">退出登录</a></el-col>
        </el-row>
      </el-header>
      <el-container>
        <el-aside width="200px">
          <!-- router 是开启路由模式,通过el-menu-item 中的index 进行跳转了 -->
          <el-menu
            router
            :uniqueOpened="true"
            :default-active="active"
            class="el-menu-vertical-demo"
            @open="handleOpen"
            @close="handleClose"
            background-color="#545c64"
            text-color="#fff"
            active-text-color="#ffd04b"
          >
            <el-menu-item
              :index="item.path"
              v-for="item in list"
              :key="item.path"
            >
              <i class="el-icon-menu"></i>
              <template #title>{{ item.meta.title }}</template>
            </el-menu-item>
          </el-menu>
        </el-aside>
        <el-main>
          <!-- 设置路由出口 -->
          <router-view></router-view>
        </el-main>
      </el-container>
    </el-container>
  </div>
</template>

<script lang="ts" setup>
import { defineComponent } from "vue";
import { useRouter,useRoute } from "vue-router";

const router = useRouter();
const route = useRoute();
console.log(router.getRoutes());
const active = route.path;

const delToken = () => {
  // 删除token
  localStorage.removeItem("token");
  // 跳转到登录页面
  router.push("/login");
};

    
     
//1.通过router 获取路由中的meta.isShow=true 的所有路由,交由下面的 el-menu-item进行遍历
const list = router.getRoutes().filter((item) => item.meta.isShow);
console.log(list);
</script>
<style lang="scss" scoped>
.el-header {
  height: 80px;
  background-color: #666;
  .logo {
    height: 80px;
  }
  h2,
  .quit-login {
    text-align: center;
    line-height: 80px;
    height: 80px;
    color: #fff;
    // 鼠标移入变为小手光标
    cursor:pointer;
  }
 
}

.el-aside {
  .el-menu {
    height: calc(100vh - 80px);
  }
}
</style>

完整的router.ts文件

import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
import Home from '../views/Home.vue'

const routes: Array<RouteRecordRaw> = [
  {
    path: '/',
    name: 'Home',
    component: Home,
    redirect: 'goods',
    children: [
      {
        path: 'goods',
        name: 'Goods',
        meta: {
          isShow: true,
          title: '商品列表'
        },
        component: () => import(/* webpackChunkName: "goods" */ '../views/Goods.vue')
      },
      {
        path: 'user',
        name: 'User',
        meta: {
          isShow: true,
          title: '用户列表'
        },
        component: () => import(/* webpackChunkName: "user" */ '../views/User.vue')
      },
      {
        path: 'role',
        name: 'Role',
        meta: {
          isShow: true,
          title: '角色列表'
        },
        component: () => import(/* webpackChunkName: "role" */ '../views/Role.vue')
      },   {
        path: 'authority',
        name: 'Authority',
        meta: {
          isShow: false,
          title: '权限列表'
        },
        component: () => import(/* webpackChunkName: "authority" */ '../views/Authority.vue')
      },
    ]
  },
  {
    path: '/about',
    name: 'About',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    // /* webpackChunkName: "about" */ webpack 的魔法命名
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  },
  {
    path: '/login',
    name: 'Login',
    component: () => import(/* webpackChunkName: "login" */ '../views/Login.vue')
  }
]

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
})

router.beforeEach((to, from, next) => { // 路由守卫
  const token: string | null = localStorage.getItem('token')
  // 如果没有token,并且去的不是登录页,就跳转到登录页
  if (!token && to.path !== '/login') {
    next('/login')
  } else {
    // 如果有token,就放行
    next()
  }
   
})
export default router

home.vue中的侧边栏代码:

<el-aside width="200px">
          <!-- router 是开启路由模式,通过el-menu-item 中的index 进行跳转了 -->
          <el-menu
            router
            :uniqueOpened="true"
            :default-active="active"
            class="el-menu-vertical-demo"
            @open="handleOpen"
            @close="handleClose"
            background-color="#545c64"
            text-color="#fff"
            active-text-color="#ffd04b"
          >
              <!-- 主要代码:2.遍历获取到的路由列表 -->
            <el-menu-item
              :index="item.path"
              v-for="item in list"
              :key="item.path"
            >
              <i class="el-icon-menu"></i>
              <template #title>{{ item.meta.title }}</template>
            </el-menu-item>
              <!-- 主要代码 -->
          </el-menu>
</el-aside>

home.vue中的内容区域:给路由一个路由出口,当点击路由后,就进行该页面的展示:

<el-main>
         <!-- 设置路由出口 -->
         <router-view></router-view>
 </el-main>