vue2实现动态侧边导航栏
2023-11-09 09:47 小罗世界 阅读(289) 评论(0) 编辑 收藏 举报
router文件下index.js 来源http://blog.itpub.net/69978258/viewspace-2909200/
// index.ts import Vue from 'vue'; import VueRouter from 'vue-router'; import Login from '@/views/login/index.vue'; import Layout from '@/layout/index.vue'; Vue.use(VueRouter); /** * hidden 表示是否需要在侧边导航栏出现 ,true表示不需要 * isFirst 表示是否只有一级权限,只出现在只有一个子集,没有其他孙子集 * 当权限拥有多个子集或者孙子集,一级权限需要加上 meta * 二级权限拥有子集,也必须有 meta */ // 基础路由 export const constantRoutes = [ { path: '/redirect', component: Layout, hidden: true, children: [ { path: '/redirect/:path(.*)', component: () => import('@/views/redirect/index.vue') } ] }, { path: '/', redirect: '/dashboard', hidden: true }, { path: '/login', name: 'Login', component: Login, hidden: true }, { path: '/dashboard', component: Layout, redirect: '/dashboard/index', isFirst: true, children: [ { path: 'index', name: 'Dashboard', component: () => import('@/views/dashboard/index.vue'), meta: { title: '首页', icon: 'el-icon-location' } } ] } ]; // 动态路由 export const asyncRoutes = [ { path: '/form', component: Layout, redirect: '/form/index', isFirst: true, children: [ { path: 'index', name: 'Form', component: () => import('@/views/form/index.vue'), meta: { title: '表单', role: 'form', icon: 'el-icon-location' } } ] }, { path: '/editor', component: Layout, redirect: '/editor/index', meta: { role: 'editors', title: '总富文本', icon: 'el-icon-location' }, children: [ { path: 'index', name: 'Editor', component: () => import('@/views/editor/index.vue'), meta: { title: '富文本', role: 'editor', icon: 'el-icon-location' } }, { path: 'two', name: 'Two', redirect: '/editor/two/three', component: () => import('@/views/editor/two.vue'), meta: { title: '二级导航', role: 'two', icon: 'el-icon-location' }, children: [ { path: 'three', name: 'Three', component: () => import('@/views/editor/three.vue'), meta: { title: '三级导航', role: 'three', icon: 'el-icon-location' } }, { path: 'four', name: 'Four', component: () => import('@/views/editor/four.vue'), meta: { title: '三级导航2', role: 'four', icon: 'el-icon-location' } } ] } ] }, { path: '/tree', component: Layout, redirect: '/tree/index', isFirst: true, children: [ { path: 'index', name: 'Tree', component: () => import('@/views/tree/index.vue'), meta: { title: '树状图', role: 'tree', icon: 'el-icon-location' } } ] }, { path: '/excel', component: Layout, redirect: '/excel/index', isFirst: true, children: [ { path: 'index', name: 'Excel', component: () => import('@/views/excel/index.vue'), meta: { title: '导入导出', role: 'excel', icon: 'el-icon-location' } } ] } ]; // 出错跳转的路由 export const error = [ // 404 { path: '/404', component: () => import('@/views/error/index.vue'), hidden: true }, { path: '*', redirect: '/404', hidden: true } ]; const createRouter = () => new VueRouter({ scrollBehavior: () => ({ x: 0, y: 0 }), routes: constantRoutes }); const router = createRouter(); // 刷新路由 export function resetRouter () { const newRouter = createRouter(); (router as any).matcher = (newRouter as any).matcher; } export default router;
页面布局代码
<!-- index.vue 用于定义页面的基础布局 --> <template> <div> <el-container> <!-- 头部 --> <el-header> <div> <p>运营后台</p> <div> <el-dropdown placement="bottom" @command="handleCommand"> <div> <img src="" alt="" /> <p>小红</p> <i class="el-icon-arrow-down el-icon--right"></i> </div> <el-dropdown-menu slot="dropdown"> <el-dropdown-item command="info">个人信息</el-dropdown-item> <el-dropdown-item command="logout">退出登录</el-dropdown-item> </el-dropdown-menu> </el-dropdown> </div> </div> </el-header> <el-container :class="{ hideSidebar: isCollapse }"> <!-- 侧边导航栏 --> <el-aside> <el-scrollbar> <el-menu :collapse="isCollapse" :default-active="$router.currentRoute.path" :collapse-transition="false" background-color="#eee" text-color="#666" active-text-color="#0099ff" @select="handleSelect" v-if="permissionRoutes" > <template v-for="item in permissionRoutes"> <el-menu-item v-if=" !item.hidden && item.children.length === 1 && item.isFirst " :index="item.redirect" :key="item.path" > <i :class="item.children[0].meta.icon"></i> <span slot="title">{{ item.children[0].meta.title }}</span> </el-menu-item> <sub-menu v-if="!item.hidden && !item.isFirst" :item="item" :key="item.path" :basePath="item.path" ></sub-menu> </template> </el-menu> </el-scrollbar> </el-aside> <!-- 主体内容 --> <el-main> <router-view /> </el-main> </el-container> </el-container> </div> </template> <script> import Vue from 'vue'; import { mapGetters } from 'vuex'; import SubMenu from '@/components/SubMenu/index.vue'; import { resetRouter } from '@/router'; export default Vue.extend({ computed: { // 路由 ...mapGetters(['permissionRoutes']) }, methods: { // 页面跳转 handleSelect (index: string) { if (this.$router.currentRoute.path === index) { return; } this.$router.push(index); }, // 下拉框选择 handleCommand (command: string) { if (command === 'logout') { localStorage.clear(); resetRouter(); this.$router.push({ name: 'Login' }); } } }, components: { SubMenu } }); </script> <style scoped> .layout { width: 100%; height: 100vh; .header-content { height: 100%; display: flex; justify-content: space-between; align-items: center; color: #fff; .header-tit { font-size: 18px; font-weight: bold; } .user-info { display: flex; align-items: center; .el-dropdown-link { display: flex; align-items: center; img { width: 35px; height: 35px; border-radius: 50%; margin-right: 10px; } .header-username { font-size: 16px; color: #fff; } } } } } /deep/.el-header { background-color: #333; } /deep/.el-main { background-color: #f2f2f2; } /deep/.el-scrollbar { height: 100%; background-color: #eee; } // 折叠展开动画 .sidebar-container { transition: width 0.28s; width: 200px !important; height: 100%; overflow: hidden; .el-menu { border: none; height: 100%; width: 100% !important; } } .hideSidebar { .sidebar-container { width: 60px !important; } } </style>