最近在学习vue.js开发,想做个简单的管理系统,研究了很长时间,看了很多慕课网的视频教程,教程地址:https://www.imooc.com/new/course/list?c=vuejs,看完教程开始试着做项目,做到后台首页被几个问题困扰了很久。

1、后台模板,模板功能怎么实现,之前都是嵌套iframe,现在怎么处理呢?研究了两天,发现这里的控制使用子路由实现,vue在路由跳转时,跳转到子路由会保留父路由的页面内容。

2、从网上下载了很多代码,都没跑起来,左侧菜单都是动态的,都得配置接口程序。

3、vue后台模板路由也需要根据接口返回权限动态实现,如果访问地址路由里面没有跳转到404页面。

本文实现的后台模板只是静态页面,动态路由、动态菜单会随着学习逐步完善。

先看看效果图:

实现思路:先创建一个主模板文件,home.vue,然后顶部是一个组件header.vue,底部是一个组件footer.vue,左侧菜单栏是一个组件Sidebar.vue,还有个tags.vue组件用于管理打开页面,中间内容部分是一个用于展示具体跳转的页面,新增完目录如下:

home页面代码:

<template><div class="wrapper"><v-head></v-head><v-sidebar></v-sidebar><div class="content-box" :class="{'content-collapse':collapse}"><div class="content_wrapper"><v-tags></v-tags><div class="content" style="flex:1;"><div class="content_inner"><transition name="move" mode="out-in"><keep-alive :include="tagsList"><router-view></router-view></keep-alive></transition></div></div><v-footer></v-footer></div></div></div>
</template><style lang="scss" scoped>.content_wrapper {display: flex;flex-direction: column;height: 100%;.content_inner {//    background: #fff;height: 100%;}}
</style><script>import vHead from './Header.vue';import vSidebar from './Sidebar.vue';import vTags from './Tags.vue';import vFooter from './Footer.vue';import bus from './bus';export default {data() {return {tagsList: [],collapse: false}},components: {vHead,vSidebar,vTags,vFooter},created() {bus.$on('collapse', msg => {this.collapse = msg;})// 只有在标签页列表里的页面才使用keep-alive,即关闭标签之后就不保存到内存中了。bus.$on('tags', msg => {let arr = [];for (let i = 0, len = msg.length; i < len; i++) {msg[i].name && arr.push(msg[i].name);}this.tagsList = arr;})}}
</script>
import vHead from './Header.vue';import vSidebar from './Sidebar.vue';import vTags from './Tags.vue';import vFooter from './Footer.vue';import bus from './bus';components: {vHead,vSidebar,vTags,vFooter},

以上代码引用各个子组件。

Header.vue代码如下:

<template><div class="header"><!-- 折叠按钮 --><div class="collapse-btn" @click="collapseChage"><i class="el-icon-menu"></i></div><div class="logo">孔子人才网后台管理系统</div><div class="header-right"><div class="header-user-con"><!-- <marquee onMouseOver="this.start()" style="font-size:18px;padding-bottom:4px;width:100px;" scrollamount="1">{{getlev}}</marquee> --><div style="font-size:18px;padding-bottom:4px;width:60px;">admin</div><!-- 全屏显示 --><div class="btn-fullscreen" @click="handleFullScreen"><el-tooltip effect="dark" :content="fullscreen?`取消全屏`:`全屏`" placement="bottom"><i class="el-icon-rank"></i></el-tooltip></div><!-- 消息中心 --><div class="btn-bell"><el-tooltip effect="dark" :content="message?`有${message}条未读消息`:`消息中心`" placement="bottom"><router-link to="/tabs"><i class="el-icon-bell"></i></router-link></el-tooltip><span class="btn-bell-badge" v-if="message"></span></div><!-- 用户头像 --><div class="user-avator"><img src="../../assets/Images/img.jpg"></div><!-- 用户名下拉菜单 --><el-dropdown class="user-name" trigger="click" @command="handleCommand"><span class="el-dropdown-link">用户名<i class="el-icon-caret-bottom"></i></span><el-dropdown-menu slot="dropdown"><a  href="https://github.com/merciqiao" target="_blank"><el-dropdown-item>关于作者</el-dropdown-item></a><a href="https://github.com/merciqiao/merciqiao-vue" target="_blank"><el-dropdown-item>项目仓库</el-dropdown-item></a><a href="/zanzhu" target="_blank"><el-dropdown-item style="color:orange;">赞助作者</el-dropdown-item></a><el-dropdown-item divided  command="changeZh">切换中文</el-dropdown-item><el-dropdown-item command="changeEn">切换英文</el-dropdown-item><el-dropdown-item divided  command="loginout">退出登录</el-dropdown-item></el-dropdown-menu></el-dropdown></div></div></div>
</template>
<script>import bus from './bus';export default {data() {return {collapse: false,fullscreen: false,name: 'merciqiao',lev:'青铜级',message: 2}},computed:{username(){let username = this.$common.getSessionStorage('username');return username ? username : this.name;},getlev(){let levList = this.$common.getSessionStorage('lev',true);let lev='';if(levList){for(var i=0;i<levList.length;i++){lev+=levList[i].roleName;}}return lev ? lev : this.lev;}},methods:{// 用户名下拉菜单选择事件handleCommand(command) {if(command == 'loginout'){this.$common.removeSessionStorage('token');this.$router.push('/login');}else if(command == 'changeZh'){this.$i18n.locale = 'zh_CN';}else if(command == 'changeEn'){this.$i18n.locale = 'en_US';}},// 侧边栏折叠collapseChage(){this.collapse = !this.collapse;bus.$emit('collapse', this.collapse);},// 全屏事件handleFullScreen(){let element = document.documentElement;if (this.fullscreen) {if (document.exitFullscreen) {document.exitFullscreen();} else if (document.webkitCancelFullScreen) {document.webkitCancelFullScreen();} else if (document.mozCancelFullScreen) {document.mozCancelFullScreen();} else if (document.msExitFullscreen) {document.msExitFullscreen();}} else {if (element.requestFullscreen) {element.requestFullscreen();} else if (element.webkitRequestFullScreen) {element.webkitRequestFullScreen();} else if (element.mozRequestFullScreen) {element.mozRequestFullScreen();} else if (element.msRequestFullscreen) {// IE11element.msRequestFullscreen();}}this.fullscreen = !this.fullscreen;}},mounted(){if(document.body.clientWidth < 1366){this.collapseChage();}}}
</script>
<style scoped>.header {position: relative;box-sizing: border-box;width: 100%;height: 70px;font-size: 22px;color: #fff;background-color: #07c4a8;}.collapse-btn{float: left;padding: 0 21px;cursor: pointer;line-height: 70px;}.header .logo{float: left;width:250px;line-height: 70px;}.header-right{float: right;padding-right: 50px;}.header-user-con{display: flex;height: 70px;align-items: center;}.btn-fullscreen{transform: rotate(45deg);margin-right: 5px;font-size: 24px;}.btn-bell, .btn-fullscreen{position: relative;width: 30px;height: 30px;text-align: center;border-radius: 15px;cursor: pointer;}.btn-bell-badge{position: absolute;right: 0;top: -2px;width: 8px;height: 8px;border-radius: 4px;background: #f56c6c;color: #fff;}.btn-bell .el-icon-bell{color: #fff;}.user-name{margin-left: 10px;}.user-avator{margin-left: 20px;}.user-avator img{display: block;width:40px;height:40px;border-radius: 50%;}.el-dropdown-link{color: #fff;cursor: pointer;}.el-dropdown-menu__item{text-align: center;}
</style>

footer.vue组件代码如下:

<template><footer><div class="footer_content"><!-- 京ICP备18050367-1 qq群:73110051(无广告) {{$t("footer.title")}}--></div></footer>
</template>
<style lang="scss">footer{border-top:1px solid #ddd;flex: 0 0 auto;.footer_content{width: 340px;margin: 0 auto;text-align: center;line-height: 60px;height: 60px;color:#606266;.qq{font-size: 9px;}}}
</style>

Siderbar.vue组件代码如下:

<template><div class="sidebar"><el-menu class="sidebar-el-menu" :default-active="onRoutes" :collapse="collapse" background-color="#324157"text-color="#bfcbd9" active-text-color="#20a0ff" unique-opened router><el-submenu index="1"><template slot="title"><i class="el-icon-location"></i><span>导航一</span></template><el-menu-item-group><template slot="title">分组一</template><el-menu-item index="1-1">选项1</el-menu-item><el-menu-item index="1-2">选项2</el-menu-item></el-menu-item-group><el-menu-item-group title="分组2"><el-menu-item index="1-3">选项3</el-menu-item></el-menu-item-group><el-submenu index="1-4"><template slot="title">选项4</template><el-menu-item index="1-4-1">选项1</el-menu-item></el-submenu></el-submenu><el-menu-item index="2"><i class="el-icon-menu"></i><span slot="title">导航二</span></el-menu-item><el-menu-item index="3" disabled><i class="el-icon-document"></i><span slot="title">导航三</span></el-menu-item><el-menu-item index="4"><i class="el-icon-setting"></i><span slot="title">导航四</span></el-menu-item></el-menu><!--<el-menu class="sidebar-el-menu" :default-active="onRoutes" :collapse="collapse" background-color="#324157"text-color="#bfcbd9" active-text-color="#20a0ff" unique-opened router><template v-for="(item,i) in menuList"><template v-if="item.subs&&item.subs.length"><el-submenu :index="item.index" :key="i"><template slot="title"><i :class="item.icon"></i><span slot="title">{{ item.title }}</span></template><el-menu-item v-for="(subItem,i) in item.subs" :key="i" :index="subItem.index">{{ subItem.title }}</el-menu-item></el-submenu></template></template></el-menu>--></div>
</template><script>import bus from './bus';import {mapGetters} from 'vuex'export default {data() {return {collapse: false,items: [{icon: 'el-icon-setting',index: 'index',title: '系统首页',},{icon: 'el-icon-tickets',index: 'table',title: '基础模块',subs: [{index: 'searchinput',title: '查询输入页'},{index: 'tabpage',title: '标签选项卡'},{index: 'tablepage',title: '综合表格页'},{index: 'formpage',title: '表单页'},{index: 'treepage',title: '树组件页'}]},{icon: 'el-icon-setting',index: '3',title: '系统管理',subs: [{index: 'organizationTree',title: '机构管理'},{index: 'sysUser',title: '用户管理'},{index: 'sysRole',title: '角色管理'},{index: 'sysAcl',title: '角色资源授权'},{index: 'sysResource',title: '资源管理'},{index: 'sysMenu',title: '菜单管理'}]},// {//     icon: 'el-icon-message',//     index: 'tabs',//     title: 'tab选项卡'// },// {//     icon: 'el-icon-date',//     index: '3',//     title: '表单相关',//     subs: [//         {//             index: 'form',//             title: '基本表单'//         },//         {//             index: 'editor',//             title: '富文本编辑器'//         },//         {//             index: 'markdown',//             title: 'markdown编辑器'//         },//         {//             index: 'upload',//             title: '文件上传'//         }//     ]// },// {//     icon: 'el-icon-star-on',//     index: 'charts',//     title: 'schart图表'// },// {//     icon: 'el-icon-rank',//     index: 'drag',//     title: '拖拽列表'// },// {//     icon: 'el-icon-warning',//     index: 'permission',//     title: '权限测试'// },{icon: 'el-icon-error',index: '404',title: '404页面'}]}},computed: mapGetters({menuList: 'getMenuList',onRoutes() {return this.$route.path.replace('/', '');}}),created() {// 通过 Event Bus 进行组件间通信,来折叠侧边栏bus.$on('collapse', msg => {this.collapse = msg;})}}
</script><style scoped>.sidebar {display: block;position: absolute;left: 0;top: 70px;bottom: 0;overflow-y: scroll;}.sidebar::-webkit-scrollbar {width: 0;}.sidebar-el-menu:not(.el-menu--collapse) {width: 250px;}.sidebar>ul {height: 100%;}
</style>

Tags.vue组件代码如下:

<template><div class="tags" v-if="showTags"><ul><li class="tags-li" v-for="(item,index) in tagsList" :class="{'active': isActive(item.path)}" :key="index"><router-link :to="item.path" class="tags-li-title">{{item.title}}</router-link><span v-show="item.title!='系统首页'" class="tags-li-icon" @click="closeTags(index)"><i class="el-icon-close"></i></span></li></ul><div class="tags-close-box"><el-dropdown @command="handleTags"><el-button size="small" type="primary">标签选项<i class="el-icon-arrow-down el-icon--right"></i></el-button><el-dropdown-menu size="medium" slot="dropdown"><el-dropdown-item command="other">关闭其他</el-dropdown-item><el-dropdown-item command="all">关闭所有</el-dropdown-item></el-dropdown-menu></el-dropdown></div></div>
</template><script>import bus from './bus';export default {data() {return {tagsList: []}},methods: {isActive(path) {return path === this.$route.fullPath;},// 关闭单个标签closeTags(index) {const delItem = this.tagsList.splice(index, 1)[0];const item = this.tagsList[index] ? this.tagsList[index] : this.tagsList[index - 1];if (item) {delItem.path === this.$route.fullPath && this.$router.push(item.path);}else{this.$router.push('/');}},// 关闭全部标签closeAll(){this.tagsList = [{name: "index",path: "/index",title: "系统首页"}];this.$router.push('/');},// 关闭其他标签closeOther(){const curItem = this.tagsList.filter(item => {return item.path === this.$route.fullPath;})this.tagsList = curItem;},// 设置标签setTags(route){const isExist = this.tagsList.some(item => {return item.path === route.fullPath;})!isExist && this.tagsList.push({title: route.meta.title,path: route.fullPath,// name: route.matched[1].components.default.namename: route.name})bus.$emit('tags', this.tagsList);},handleTags(command){command === 'other' ? this.closeOther() : this.closeAll();}},computed: {showTags() {return this.tagsList.length > 0;}},watch:{$route(newValue, oldValue){this.setTags(newValue);}},created(){this.setTags(this.$route);}}</script><style lang="scss">$tag_height:34px;//tab高度变量.tags {position: relative;height: $tag_height;overflow: hidden;background: #fff;padding-right: 120px;flex: 0 0 auto;}.tags ul {box-sizing: border-box;width: 100%;height: 100%;}.tags-li {float: left;margin: 3px 5px 2px 3px;border-radius: 3px;font-size: 12px;overflow: hidden;cursor: pointer;height: $tag_height - 8px;line-height: $tag_height - 8px;border: 1px solid #e9eaec;background: #fff;padding: 0 5px 0 12px;vertical-align: middle;color: #666;-webkit-transition: all .3s ease-in;-moz-transition: all .3s ease-in;transition: all .3s ease-in;}.tags-li:not(.active):hover {background: #f8f8f8;}.tags-li.active {color: #fff;}.tags-li-title {float: left;max-width: 80px;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;margin-right: 5px;color: #666;}.tags-li.active .tags-li-title {color: #fff;}.tags-close-box {position: absolute;right: 0;top: 0;box-sizing: border-box;padding-top: 1px;text-align: center;width: 110px;height: $tag_height;background: #fff;box-shadow: -3px 0 15px 3px rgba(0, 0, 0, .1);z-index: 10;}</style>

最后修改路由配置文件,代码如下:

const routes = [{path: '/',name: 'Login',component: Login},{name: 'Home',path: '/Home',component: Home,meta: {title: '系统首页'}}
]

项目创建是用的vue cli3脚手架创建的。

Vue 2.x + Element后台模板开发教程(三)后台首页模板设计相关推荐

  1. 来自damon的zencart二次开发教程-3.2复制模板(仿站)操作教程

    用zencart来复制别人的网站成本低,效率高.前面我发了一篇有关开发自己的zencat模板的文章(<来自damon的zencart二次开发教程-3.1开发自己的zencart模板>),里 ...

  2. Django 3.2.5博客开发教程:一些常用的模板使用方法

    一.django static文件的引入方式 1.在django project中创建 static文件夹 2.settings.py中配置要在 STATIC_URL = '/static/' 下边 ...

  3. 《开源网店系统iWebShop2.0模板开发教程》的说明

    <开源网店系统iWebShop2.0模板开发教程>是网上广为流传的一个文档,有点问题. 其中的第4章: ========================================== ...

  4. Django 3.2.5博客开发教程:实现网站首页

    实现首页模板前,我们先把共公的页面模板base.html调用好.首先我们先看导航部分,除开首页和关于博主之外,其它的其实是我们的文章分类名.如图: 我们只需要在首页视图函数里,查询出所有的文章分类名称 ...

  5. MIP开发教程(三) 使用MIP-CLI工具调试组件

    一 . 在 mip-extensions 仓库中创建新的组件 二 . 预览调试组件 三 . 在 MIP 页中引用自己编写的 MIP 组件 四 . 组件提交到 GitHub 仓库时需要进行校验 站长开发 ...

  6. 帝国cms【官方教程系列教程一】 首页模板制作

    帝国cms首页模板是指网站首页的模板.(/index.html) 修改首页模板 1.登录后台,单击"模板"菜单,选择"首页模板"子菜单,进入修改首页模板界面: ...

  7. 【100个高大尚求职简历】简历模板+修改教程+行业分类简历模板 (涵盖各种行业) (简历模板+编辑指导+修改教程)

    文章目录 1 简历预览 2 简历下载 很多人说自己明明投了很多公司的简历,但是都没有得到面试邀请的机会.自己工作履历挺好的,但是为什么投自己感兴趣公司的简历,都没有面试邀请的机会.反而是那些自己没有投 ...

  8. 帝国cms模板开发教程(八):帝国cms封面模板开发

    前面学习了帝国cms首页模板的开发,我们开始学习帝国cms封面页面模板的制作,下面一起来学习帝国cms封面页面模板的写入! 首先,我们先看一下案例图片 案例网址:http://ecms.qinshin ...

  9. 帝国cms模板开发教程(二):了解帝国cms模板核心构成页面有哪些?

    在进行帝国cms模板开发之前,我们首先需要了解帝国cms模板核心构成页面有哪些?哪些是核心页面?哪些是根据建站不同需要定制的页面. 1.核心构成页面 a.首页(核心) b.列表页(核心) c.内容页( ...

  10. 微信开发(三)微信模板消息接口设计

    说明 在公司微信项目开发中,我主要负责消息中心的模板消息接口设计实现.主要是将微信公众号的推送模板消息功能放到公司的消息中心系统中,微信后台项目通过RMI调用接口,实现推送功能.在这里记录总结下当时的 ...

最新文章

  1. ASP.NET禁用视图状态
  2. 光子人工智能芯片助“中国芯”换道超车
  3. Runtime知识点整理
  4. 【Storm篇】--Storm基础概念
  5. 26.Azure备份服务器(下)
  6. 关于JAVA中子类和父类的构造方法
  7. TensorFlow for Hackers - Part II
  8. Dokcer安装Redis
  9. Navicate Premium连接Oracle数据库报错
  10. SAP成都研究院大卫哥:SAP C4C中国本地化之微信小程序集成
  11. 机器学习从理论到工程的第一步-编程语言篇
  12. ROS(3)订阅者subscriber编程实现
  13. 项目 我行我素购物管理系统 0913
  14. IntelliJ Idea学习笔记001--- IntelliJ Idea常用快捷键列表
  15. android 左移动画_android 动画Animation之TranslateAnimation移动
  16. SSM服装销售商城,毕业论文+源码+包运行
  17. 世界各国简称 英文名称 电话区号JSON数据包
  18. The project seems to require yarn but it‘s not installed.
  19. 计算机人才供需状况和就业形势分析,计算机科学与技术就业形势分析
  20. 《NLTK基础教程》读书笔记 006期

热门文章

  1. BIP-39, BIP32/BIP-44
  2. 快速排序(java实现)
  3. win7桌面右下角的音量图标不见了怎么办
  4. windows截图快捷方式
  5. Cesium: 如何将倾斜摄影数据转换为3dTiles格式
  6. 小猫钓鱼纸牌游戏java_小猫钓鱼游戏-关于扑克牌的游戏规则请问小猫钓鱼这种玩法的 – 手机爱问...
  7. 数理统计 -次序统计量、充分统计量
  8. 开源ESB-ServiceMix服务总线
  9. 人生感悟经典哲理句子,句句都是人生哲理!
  10. 基于Spire.PDF将HTML转换为PDF