Vue2项目练手——通用后台管理项目
- 路由限制重复跳转
- CommonAside.vue
- 顶部header组件搭建与样式修改
- 右边用户菜单栏
- 使用的组件
- 图片
- CommonHeader.vue
- Vuex实现左侧折叠
- 文件目录
- store/index.js
- store/tab.js
- main.js
- CommonHeader.vue
- CommonAside.vue
- Main.vue
路由限制重复跳转
路由重复跳转会出现bug
解决路由重复bug问题:
clickMenu(item){// console.log(item)// console.log(this.$route.path)// 当页面的路由与跳转的路由不一致才允许跳转if(this.$route.path!==item.path && !(this.$route.path==='/home'&&(item.path==='/'))){this.$router.push(item.path)}}
CommonAside.vue
<template><el-menu default-active="1-4-1" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose":collapse="isCollapse" background-color="#545c64" text-color="#fff"active-text-color="#ffd04b"><h3>通用后台管理系统</h3><el-menu-item @click="clickMenu(item)" v-for="item in noChildren" :key="item.name" :index="item.name"><i :class="`el-icon-${item.icon}`"></i><span slot="title">{{item.label}}</span></el-menu-item><el-submenu :index="item.label" v-for="item in hasChildren" :key="item.label"><template slot="title"><i :class="`el-icon-${item.icon}`"></i><span slot="title">{{item.label}}</span></template><el-menu-item-group><el-menu-item @click="clickMenu(subItem)" :index="subItem.path" :key="subItem.path" v-for="subItem in item.children">{{subItem.label}}</el-menu-item></el-menu-item-group></el-submenu></el-menu></template><style lang="less" scoped>
.el-menu-vertical-demo:not(.el-menu--collapse) {width: 200px;min-height: 400px;
}
.el-menu{height: 100vh; //占据页面高度100%h3{color: #fff;text-align: center;line-height: 48px;font-size: 16px;font-weight: 400;}
}
</style><script>
export default {data() {return {isCollapse: false,menuData:[{path:'/',name:"home",label:"首页",icon:"s-home",url:'Home/Home'},{path:'/mall',name:"mall",label:"商品管理",icon:"video-play",url:'MallManage/MallManage'},{path:'/user',name:"user",label:"用户管理",icon:"user",url:'userManage/userManage'},{label:"其他",icon:"location",children:[{path:'/page1',name:"page1",label:"页面1",icon:"setting",url:'Other/PageOne'},{path:'/page2',name:"page2",label:"页面2",icon:"setting",url:'Other/PageTwo'},]},]};},methods: {handleOpen(key, keyPath) {console.log(key, keyPath);},handleClose(key, keyPath) {console.log(key, keyPath);},clickMenu(item){// console.log(item)// console.log(this.$route.path)// 当页面的路由与跳转的路由不一致才允许跳转if(this.$route.path!==item.path && !(this.$route.path==='/home'&&(item.path==='/'))){this.$router.push(item.path)}}},mounted() {console.log(this.$route.path)},computed:{//没有子菜单的数据noChildren(){return this.menuData.filter(item=>!item.children)},//有子菜单数组hasChildren(){return this.menuData.filter(item=>item.children)}}
}
</script>
顶部header组件搭建与样式修改
右边用户菜单栏
使用的组件
图片
CommonHeader.vue
<template><div class="header-container"><div class="l-content"><el-button icon="el-icon-menu" size="mini"></el-button><!-- 面包屑--><span class="text">首页</span></div><div class="r-content"><el-dropdown><span class="el-dropdown-link"><img src="@/assets/user.webp" alt=""></span><el-dropdown-menu slot="dropdown"><el-dropdown-item>个人中心</el-dropdown-item><el-dropdown-item>退出</el-dropdown-item></el-dropdown-menu></el-dropdown></div></div></template><script>
export default {name: "CommonHeader",
}
</script><style scoped lang="less">
.header-container {height: 60px;background-color: #333;display: flex;justify-content: space-between;align-items: center;padding: 0 20px;.text {color: #fff;font-size: 14px;margin-left: 10px;}.r-content{img{width: 40px;height: 40px;border-radius: 50%;}}
}
</style>
Vuex实现左侧折叠
文件目录
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import tab from './tab'Vue.use(Vuex)
export default new Vuex.Store({modules:{tab}
})
store/tab.js
export default {state:{isCollapse:false //控制菜单的展开还是收起},mutations:{// 修改菜单展开收起的方法collapseMenu(state){state.isCollapse=!state.isCollapse}}
}
main.js
import Vue from 'vue'
import App from './App.vue'
import VueRouter from "vue-router";
import router from "@/router";
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css'
import store from '@/store'
Vue.config.productionTip = false
Vue.use(VueRouter)
Vue.use(ElementUI)
new Vue({store,router,render: h => h(App),
}).$mount('#app')
CommonHeader.vue
<template><div class="header-container"><div class="l-content"><el-button icon="el-icon-menu" size="mini" @click="handleMenu"></el-button><!-- 面包屑--><span class="text">首页</span></div><div class="r-content"><el-dropdown><span class="el-dropdown-link"><img src="@/assets/user.webp" alt=""></span><el-dropdown-menu slot="dropdown"><el-dropdown-item>个人中心</el-dropdown-item><el-dropdown-item>退出</el-dropdown-item></el-dropdown-menu></el-dropdown></div></div></template><script>
export default {name: "CommonHeader",methods:{handleMenu(){this.$store.commit('collapseMenu')}}
}
</script><style scoped lang="less">
.header-container {height: 60px;background-color: #333;display: flex;justify-content: space-between;align-items: center;padding: 0 20px;.text {color: #fff;font-size: 14px;margin-left: 10px;}.r-content{img{width: 40px;height: 40px;border-radius: 50%;}}
}
</style>
CommonAside.vue
<template><el-menu default-active="1-4-1" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose":collapse="isCollapse" background-color="#545c64" text-color="#fff"active-text-color="#ffd04b"><h3>{{isCollapse?'后台':'通用后台管理系统'}}</h3><el-menu-item @click="clickMenu(item)" v-for="item in noChildren" :key="item.name" :index="item.name"><i :class="`el-icon-${item.icon}`"></i><span slot="title">{{item.label}}</span></el-menu-item><el-submenu :index="item.label" v-for="item in hasChildren" :key="item.label"><template slot="title"><i :class="`el-icon-${item.icon}`"></i><span slot="title">{{item.label}}</span></template><el-menu-item-group><el-menu-item @click="clickMenu(subItem)" :index="subItem.path" :key="subItem.path" v-for="subItem in item.children">{{subItem.label}}</el-menu-item></el-menu-item-group></el-submenu></el-menu></template><style lang="less" scoped>
.el-menu-vertical-demo:not(.el-menu--collapse) {width: 200px;min-height: 400px;
}
.el-menu{height: 100vh; //占据页面高度100%h3{color: #fff;text-align: center;line-height: 48px;font-size: 16px;font-weight: 400;}
}
</style><script>
export default {data() {return {menuData:[{path:'/',name:"home",label:"首页",icon:"s-home",url:'Home/Home'},{path:'/mall',name:"mall",label:"商品管理",icon:"video-play",url:'MallManage/MallManage'},{path:'/user',name:"user",label:"用户管理",icon:"user",url:'userManage/userManage'},{label:"其他",icon:"location",children:[{path:'/page1',name:"page1",label:"页面1",icon:"setting",url:'Other/PageOne'},{path:'/page2',name:"page2",label:"页面2",icon:"setting",url:'Other/PageTwo'},]},]};},methods: {handleOpen(key, keyPath) {console.log(key, keyPath);},handleClose(key, keyPath) {console.log(key, keyPath);},clickMenu(item){// console.log(item)// console.log(this.$route.path)// 当页面的路由与跳转的路由不一致才允许跳转if(this.$route.path!==item.path && !(this.$route.path==='/home'&&(item.path==='/'))){this.$router.push(item.path)}}},mounted() {console.log(this.$route.path)},computed:{//没有子菜单的数据noChildren(){return this.menuData.filter(item=>!item.children)},//有子菜单数组hasChildren(){return this.menuData.filter(item=>item.children)},isCollapse(){return this.$store.state.tab.isCollapse}}
}
</script>
Main.vue
<template><div><el-container><el-aside width="auto"><CommonAside></CommonAside></el-aside><el-container><el-header><CommonHeader></CommonHeader></el-header><el-main>
<!-- 路由出口,路由匹配到的组件将渲染在这里 --><router-view></router-view></el-main></el-container></el-container></div></template><script>
import CommonAside from "@/components/CommonAside.vue";
import CommonHeader from "@/components/CommonHeader.vue";
export default {name: "Main",components:{CommonAside,CommonHeader}
}
</script><style scoped>
.el-header{padding: 0;margin: 0;
}
.el-menu{border-right: none;
}
</style>