Element UI 是一套采用 Vue 2.0 作为基础框架实现的组件库,它面向企业级的后台应用,能够帮助你快速地搭建网站,极大地减少研发的人力与时间成本。今天我就把实际运用中的布局跟大家说一下,希望对大家有用。今天我主要讲的是登录后的布局界面,原来我们都是用frameset布局,现在我们要用Element看看如何实现。
界面截图
这种布局用frameset可以这么写:
<frameset rows="100,*" cols="*" scrolling="No" framespacing="0" frameborder="no" border="0"> <frame src="inc/head.html" name="headmenu" id="mainFrame" title="mainFrame"><!-- 引用头部 --> <!-- 引用左边和主体部分 --> <frameset rows="100*" cols="220,*" scrolling="No" framespacing="0" frameborder="no" border="0"> <frame src="inc/left.html" name="leftmenu" id="mainFrame" title="mainFrame"> <frame src="main.html" name="main" scrolling="yes" noresize="noresize" id="rightFrame" title="rightFrame"> </frameset></frameset>
那么我们如何用Element来写呢,具体步骤如下。
一、创建项目
这个就不用说了,我把我自己的项目结构贴出来。
项目结构
二、创建页眉、左侧、右侧文件
首先,我们创建头部、左边、右边文件,我们他们都创建在src-->components文件夹下,具体如下:
<!--头部(Header.vue)--><template> <div> <div class="topbar-logo topbar-btn"> <a href="/">![](../../static/i/logo.png)</a> </div> <div class="topbar-title topbar-btn"> <span>后台管理系统</span> </div> <div class="topbar-account topbar-btn"> <el-dropdown trigger="click"> <span class="el-dropdown-link userinfo-inner"><i class="iconfont icon-user"></i> {{sysUserName}} <i class="iconfont icon-down"></i></span> <el-dropdown-menu slot="dropdown"> <el-dropdown-item @click.native="userinfo">个人信息</el-dropdown-item> <el-dropdown-item @click.native="editpwd">修改密码</el-dropdown-item> <el-dropdown-item divided @click.native="logout">退出登录</el-dropdown-item> </el-dropdown-menu> </el-dropdown> </div> </div></template><script type="text/ecmascript-6"> export default { data() { return { sysUserName: '', sysUserAvatar: '', collapsed: false, } }, mounted() { var userSession = this.getCookie('session'); if(userSession) { this.sysUserName = userSession || ''; } }, methods: { //退出 logout() { this.$confirm('确认要退出吗?','提示',{}).then(() => { this.$fetch('m/logout').then((res) =>{ if(res.errCode == 200) { this.delCookie('session'); this.delCookie('u_uuid'); this.$router.push({path: '/', query: {redirect: this.$router.currentRoute.fullPath}}); } else { console.log(res.errMsg); } }); }).catch(() => { }); }, //个人信息 userinfo() { this.$router.push('/userinfo'); }, //修改密码 editpwd() { this.$router.push('/editpwd'); } } }</script>标签具体是什么意思,我就不解释了,大家可以看看Element官网(http://element.eleme.io/#/)
<!--左边(UserLeft.vue)--><template> <div> <aside :class="collapsed?'menu-collapsed' : 'menu-expanded'"> <!--展开折叠开关--> <div class="menu-toggle" @click.prevent="collapse"> <i class="iconfont icon-menufold" v-show="!collapsed"></i> <i class="iconfont icon-menuunfold" v-show="collapsed"></i> </div> <!--菜单展开时的显示情况--> <el-menu v-show="!collapsed" default-active="0" @open="handleOpen" @close="handleClose" router> <template v-for="(item,index) in $router.options.routes" v-if="item.menuShow"> <el-submenu v-if="!item.leaf" :index="index+''"> <template slot="title"><i :class="item.iconCls"></i>{{item.name}}</template> <el-menu-item v-for="term in item.children" :key="term.path" :index="term.path" v-if="term.menuShow"> {{term.name}} </el-menu-item> </el-submenu> <el-menu-item v-else-if="item.leaf&&item.children&&item.children.length" :index="item.children[0].path" class="el-submenu__title"> <i :class="item.iconCls"></i>{{item.children[0].name}} </el-menu-item> </template> </el-menu> <!--菜单折叠后的显示情况 这里需要说明一下: $router.options.routes,其实就是从路由获取菜单数据,具体往下面看。这是重点,要不然你都不知道数据从哪里过来的。其实这里的数据可以做到数据库中,然后直接从数据库中获取。 --> <ul v-show="collapsed" class="el-menu collapsed" ref="menuCollapsed" > <template v-for="(item,index) in $router.options.routes" v-if="item.menuShow"> <li v-if="!item.leaf" :index="index+''" style="position: relative;"> <div class="el-submenu__title" style="padding-left: 20px;" @mouseover="showMenu(index,true)" @mouseout="showMenu(index,false)"><i :class="item.iconCls"></i></div> <ul class="el-menu submenu" :class="'submenu-hook-'+index" @mouseover="showMenu(index,true)" @mouseout="showMenu(index,false)"> <li v-for="term in item.children" :key="term.path" v-if="term.menuShow" class="el-menu-item" style="padding-left: 40px;" :class="$route.path==term.path?'is-active':''" @click="$router.push(term.path)">{{term.name}}</li> </ul> </li> <li v-else-if="item.leaf&&item.children&&item.children.length" class="el-menu-item el-submenu__title" :class="$route.path==item.children[0].path?'is-active':''" @click="$router.push(item.children[0].path)"> <i :class="item.iconCls"></i> </li> </template> </ul> </aside> </div></template><script> export default { data() { return { sysUserName: '', sysUserAvatar: '', collapsed: false } }, mounted() { //初始化 }, methods: { handleOpen() { }, handleClose() { }, //折叠导航栏 collapse: function () { this.collapsed = !this.collapsed; }, showMenu(i, status){ this.$refs.menuCollapsed.getElementsByClassName('submenu-hook-' + i)[0].style.display = status ? 'block' : 'none'; } } }</script>
<!-- 右边(UserRight.vue)这是初始化的页面,大家可以根据自己的需求来写 --><template> <div> <el-row class="warp"> <el-col :span="24" class="warp-breadcrum"> <el-breadcrumb separator="/"> <el-breadcrumb-item :to="{path:'/'}"><b>首页</b></el-breadcrumb-item> </el-breadcrumb> </el-col> <el-col :span="24" class="warp-main"> <section class="chart-container"> <el-row> <el-col :span="3"> <el-card> ![](../../static/i/logo.png) <div style="padding: 14px;"> <span>公司LOGO</span> <div class="bottom clearfix"> <time class="time">{{currentDate | formatDate(1)}}</time> </div> </div> </el-card> </el-col> </el-row> </section> </el-col> </el-row> </div></template><script> export default { data() { return { currentDate: new Date(), } } }</script>
三、创建路由文件
<!--打开路由文件复制如下代码 -->import Vue from 'vue'import Router from 'vue-router'import Index from '@/views/index/Index' //首页import Home from '@/views/index/Home' //主页import right from '@/components/UserRight' //右侧import userlist from '@/views/user/UserList' //用户列表import usercert from '@/views/user/Certification' //用户审核import userlook from '@/views/user/UserLook' //用户查看import usercertlook from '@/views/user/UserCertLook' //用户审核查看import sellbill from '@/views/ticket/SellBill' //卖票信息import buybill from '@/views/ticket/BuyBill' //买票信息import changebill from '@/views/ticket/ChangeBill' //换票信息import billlist from '@/views/bill/list' //票据列表import billinfo from '@/views/bill/info' //票据详细import addbill from '@/views/bill/add' //添加票据import editsellbill from '@/views/ticket/EditSellBill' //修改卖票信息import editbuybill from '@/views/ticket/EditBuyBill' //修改买票信息import editchangebill from '@/views/ticket/EditChangeBill' //修改换票信息import lookbill from '@/views/ticket/LookBill' //查看详细import lookbuybill from '@/views/ticket/LookBuyBill' //查看买票详细import ticketstatus from '@/views/ticket/TicketStatus' //票据状态import addticket from '@/views/ticket/AddTicket' //新建开票信息import userinfo from '@/views/user/UserInfo' //个人信息import editpwd from '@/views/user/EditPwd' //修改密码import webbasic from '@/views/user/WebBasic' //网站基本配置/* 图片管理 */import imglist from '@/views/image/ImgList' //图片列表import addimg from '@/views/image/AddImg' //图片添加import editimg from '@/views/image/EditImg' //图片编辑/* 新闻信息 */import newtype from '@/views/newstype/TypeList' //新闻分类import addnewstype from '@/views/newstype/AddType' //添加新闻分类import editnewstype from '@/views/newstype/EditType' //编辑新闻分类import newlist from '@/views/news/NewsList' //新闻列表import addnews from '@/views/news/AddNews' //添加新闻import editnews from '@/views/news/EditNews' //编辑新闻import looknews from '@/views/news/LookNews' //查看新闻/* 帮助中心 */import addhelp from '@/views/help/AddHelp' //添加帮助import helplist from '@/views/help/HelpList' //帮助列表import edithelp from '@/views/help/EditHelp' //帮助修改import lookhelp from '@/views/help/LookHelp' //帮助查看import industry from '@/views/help/Industry' //行业解决方案import security from '@/views/help/Security' //安全保障/* 友情链接*/import linklist from '@/views/link/LinkList' //友情链接列表import addlink from '@/views/link/AddLink' //添加友情链接import editlink from '@/views/link/EidtLink' //编辑友情链接/* 关于我们 */import addabout from '@/views/aboutus/AddAbout' //添加关于我们import aboutlist from '@/views/aboutus/AboutList' //添加关于我们import lookabout from '@/views/aboutus/LookAbout' //查看关于我们import editabout from '@/views/aboutus/EditAbout' //编辑关于我们Vue.use(Router); <!-- 以下就是导航菜单,也就是前面我们看到。下面我解释以下相关参数: path:路径,默认为:"/", name:标题 compnent:组件, redirect:跳转页面 menuShow:true or false;控制左侧菜单显示还是隐藏 iconCls:图标样式 children:子模块,这里表示主菜单下面挂载多个子菜单 meta:{requireAuth: true },主要做登录判断,具体的实现方式在下面的页面路由验证 -->const routes = [ { path: '/', name:'登录', component:Index }, { path: '/', name: 'home', component: Home, redirect: '/home', leaf: true, //只有一个节点 menuShow: true, iconCls: 'iconfont icon-home', //图标样式 children: [ {path:'/home', component: right, name: '首页', menuShow: true, meta:{requireAuth: true }} ] }, { path: '/', component: Home, name: '用户管理', menuShow: true, iconCls: 'iconfont icon-users', children: [ {path: '/userlist', component: userlist, name: '用户列表', menuShow: true, meta:{requireAuth: true }}, {path: '/usercert', component: usercert, name: '用户认证审核', menuShow: true, meta:{requireAuth: true }}, {path: '/userlook', component: userlook, name: '查看用户信息', menuShow: false,meta:{requireAuth: true}}, {path: '/usercertlook', component: usercertlook, name: '用户审核信息', menuShow: false,meta:{requireAuth: true}}, ] }, { path: '/', component: Home, name: '信息管理', menuShow: true, iconCls: 'iconfont icon-books', children: [ {path: '/sellbill', component: sellbill, name: '卖票信息', menuShow: true, meta:{requireAuth: true }}, {path: '/buybill', component: buybill, name: '买票信息', menuShow: true, meta:{requireAuth: true }}, {path: '/changebill', component: changebill, name: '换票信息', menuShow: true, meta:{requireAuth: true }}, {path: '/bill/editsellbill', component: editsellbill, name: '编辑卖票信息', menuShow: false, meta:{requireAuth: true}}, {path: '/bill/editbuybill', component: editbuybill, name: '编辑买票信息', menuShow: false, meta:{requireAuth: true}}, {path: '/bill/editchangebill', component: editchangebill, name: '编辑换票信息', menuShow: false, meta:{requireAuth: true}}, {path: '/bill/lookbill', component: lookbill, name: '查看票据信息', menuShow: false, meta:{requireAuth: true}}, {path: '/bill/lookbuybill', component: lookbuybill, name: '查看买票信息', menuShow: false, meta:{requireAuth: true}} ] }, { path: '/bill', component: Home, name: '票据管理', menuShow: true, iconCls: 'iconfont icon-books', children: [ {path: '/bill/list', component: billlist,name: '已开票据列表', menuShow: true, meta:{requireAuth: true }}, {path: '/bill/info', component: billinfo,name: '票据详细页', menuShow: false, meta:{requireAuth: true }}, {path: '/bill/add', component: addbill, name: '新建开票信息', menuShow: true, meta:{requireAuth: true }}, {path: '/bill/update', component: addbill, name: '修改票据信息', menuShow: false, meta:{requireAuth: true }} ] }, { path: '/', component: Home, name: '资讯管理', menuShow: true, iconCls: 'iconfont icon-books2', children: [ {path: '/newtype/newtype', component: newtype, name: '资讯分类', menuShow: true, meta:{requireAuth: true}}, {path: '/newtype/addnewstype', component: addnewstype, name: '添加资讯分类', menuShow: false, meta:{requireAuth: true}}, {path: '/newtype/editnewstype', component: editnewstype, name: '编辑资讯分类', menuShow: false, meta:{requireAuth: true}}, {path: '/new/newlist', component: newlist, name: '资讯列表', menuShow: true, meta:{requireAuth: true}}, {path: '/new/addnews', component: addnews, name: '添加新闻', menuShow: false, meta:{requireAuth: true}}, {path: '/new/editnews', component: editnews, name: '编辑新闻', menuShow: false, meta:{requireAuth: true}}, {path: '/new/looknews', component: looknews, name: '查看新闻', menuShow: false, meta:{requireAuth: true}} ] }, { path: '/', component: Home, name: '关于我们', menuShow: true, iconCls: 'iconfont icon-books1', children: [ {path: '/aboutus/addabout', component: addabout, name: '添加关于我们', menuShow: true, meta:{requireAuth: true}}, {path: '/aboutus/aboutlist', component: aboutlist, name: '关于我们', menuShow: true, meta:{requireAuth: true}}, {path: '/aboutus/lookabout', component: lookabout, name: '查看关于我们', menuShow: false, meta:{requireAuth: true}}, {path: '/aboutus/editabout', component: editabout, name: '编辑关于我们', menuShow: false, meta:{requireAuth: true}} ] }, { path: '/', component: Home, name: '帮助管理', menuShow: true, iconCls: 'iconfont icon-books2', children: [ {path: '/help/addhelp', component: addhelp, name: '添加帮助', menuShow: true, meta:{requireAuth: true}}, {path: '/help/helplist', component: helplist, name: '帮助中心', menuShow: true, meta:{requireAuth: true}}, {path: '/help/edithelp', component: edithelp, name: '编辑帮助信息', menuShow: false, meta:{requireAuth: true}}, {path: '/help/lookhelp', component: lookhelp, name: '查看帮助信息', menuShow: false, meta:{requireAuth: true}} ] }, { path: '/', component: Home, name: '图片管理', menuShow: true, iconCls: 'iconfont icon-setting1', children: [ {path: '/img/addimg', component: addimg, name: '添加图片', menuShow: true, meta:{requireAuth: true }}, {path: '/img/imglist', component: imglist, name: '图片管理', menuShow: true, meta:{requireAuth: true }}, {path: '/img/editimg', component: editimg, name: '编辑图片', menuShow: false, meta:{requireAuth: true }} ] }, { path: '/', component: Home, name: '友情链接', menuShow: true, iconCls: 'iconfont icon-setting1', children: [ {path: '/link/addlink', component: addlink, name: '添加友情链接', menuShow: true, meta:{requireAuth: true }}, {path: '/link/linklist', component: linklist, name: '友情链接管理', menuShow: true, meta:{requireAuth: true }}, {path: '/link/editlink', component: editlink, name: '编辑友情链接', menuShow: false, meta:{requireAuth: true }} ] }, { path: '/', component: Home, name: '系统设置', menuShow: true, iconCls: 'iconfont icon-setting1', children: [ {path: '/userinfo', component: userinfo, name: '个人信息', menuShow: true, meta:{requireAuth: true }}, {path: '/editpwd', component: editpwd, name: '修改密码', menuShow: true, meta:{requireAuth: true }}, {path: '/webbasic', component: webbasic, name: '基本配置', menuShow: true, meta:{requireAuth: true }}, ] } ];const router = new Router({ routes }); <!--这个是请求页面路由的时候会验证token存不存在,不存在的话会到登录页 这段代码大家可以根据自己的需求来写,不一定按照我写的。 --> router.beforeEach((to, from, next) => { if(to.meta.requireAuth) { fetch('m/is/login').then(res => { if(res.errCode == 200) { next(); } else { if(getCookie('session')) { delCookie('session'); } if(getCookie('u_uuid')) { delCookie('u_uuid'); } next({ path: '/' }); } }); } else { next(); } }); export default router;
四、样式文件
<!--创建app.css 在 static-->css创建app.css-->/*全局 */body{padding:0; margin:0; background: #333744;}#app{font-family: "Microsoft Yahei", sans-serif !important; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;color: #2c3e50;text-align: left;}/*框架css */.page{height:100%; background-color: #fff; position:absolute; overflow: hidden; zoom:1; width:100%;}header{height:8%; background-color: #666;}.content{height:92%; background-color: #f50; position:absolute; overflow: hidden; zoom:1; width:100%;}.left{width:200px; height: 100%; background-color: #333744; float:left; overflow: hidden; zoom:1;}.right{background-color: #fff; height:100%; overflow-y: auto;}/*自定义css */.el-text-left{ text-align: left;}.el-text-right{ text-align: right;}.el-text-center{ text-align: center;}.visibilityH{visibility: hidden;}.el-no-bold{font-weight: normal;}.el-bold{font-weight: bold;}/*修改自带样式*/.el-dropdown-menu{font-size:14px; font-family: "Microsoft Yahei", sans-serif; line-height:20px;}/* 登录页 */.login-container{margin:10pc auto;padding:35px 35px 15px;width:350px;border:1px solid #eaeaea;border-radius:5px;background:#fff;background:-webkit-gradient(linear,0 0,0 100%,from(#b8c4cb),to(#f6f6f8));background:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#6495ed));background:-webkit-linear-gradient(top,#fff,#6495ed,#fff);background:-o-linear-gradient(top,#fff,#6495ed);background-clip:padding-box;box-shadow:0 0 25px #cac6c6}.title{margin:0 auto 40px;color:#505458;text-align:center}.remember{margin:0 0 35px}.el-menu-item,.el-submenu__title{color:#fff}.el-submenu__title:hover{background-color:#00c1de}.el-submenu .el-menu-item{background-color:#333744}.el-submenu .el-menu-item:hover{background-color:#4a5064}.el-menu-item.is-active,.el-menu-item.is-active:hover,.el-submenu .el-menu-item.is-active,.el-submenu .el-menu-item.is-active:hover{background-color:#00c1de;color:#fff}.el-menu .iconfont{margin-right:6px;vertical-align:baseline}.warp-breadcrum{padding:10px 0;border-bottom:1px solid #efefef}.warp-main{padding-top:20px}.container{position:absolute;top:0;bottom:0;width:100%}.topbar-wrap{padding:0;height:50px;background:#1d8ce0;line-height:50px}.topbar-btn{color:#fff}.topbar-btn:hover{background-color:#58b7ff}.topbar-logo{width:49px;line-height:26px}.topbar-logo,.topbar-title{float:left;border-right:1px solid #1d8ce0;text-align:center}.topbar-title{width:129px}.topbar-account{float:right;padding-right:9pt;font-size:9pt}.userinfo-inner{padding-left:10px;color:#fff;cursor:pointer}.main{position:absolute;top:50px;bottom:0;display:flex;overflow:hidden}aside{width:180px;flex:0 0 180px}.el-menu{height:100%;border-radius:0;background-color:#333744}.collapsed{width:50px}.submenu{position:absolute;top:0;left:50px;z-index:9999;display:none;height:auto}.menu-collapsed{width:50px;flex:0 0 50px}.menu-expanded{width:180px;flex:0 0 180px}.menu-toggle{height:26px;background:#4a5064;color:#fff;text-align:center;line-height:30px}.content-container{overflow-y:auto;padding:10px;background:#fff;flex:1}.content-wrapper{box-sizing:border-box;background-color:#fff}.time{color:#999;font-size:13px}.bottom{margin-top:13px;line-height:9pt}/*票据管理 */.breadcrumb{ border-bottom:1px dotted #dfe6ec; padding-bottom:10px; padding-left:10px;}.my-el-table .el-table{font-size:12px;}.right-title{font-size:16px; font-weight: normal; margin-top:15px;}a.table-right-link{color:rgb(32, 160, 255); text-decoration: none;}/*票据详细 */.my-table{border:1px solid #dfe6ec; margin: 30px auto 0; border-collapse: collapse;}.my-table .caption{font-size:24px;}.my-table td{padding:10px 13px; border:1px solid #dfe6ec; font-size:14px;}.my-table .table-title{background-color: #EFF2F7;}.bill-images{width:70%; margin:20px auto;}.right-btn{float: right;}/*图片上传*/.avatar-uploader .el-upload { border: 1px dashed #d9d9d9; border-radius: 6px; cursor: pointer; position: relative; overflow: hidden; }.avatar-uploader .el-upload:hover { border-color: #20a0ff; }.avatar-uploader-icon {font-size: 28px; color: #8c939d; width: 120px; height: 120px; line-height: 120px; text-align: center; }.avatar {width: 120px; height: 120px; display: block; }/*添加票据 */.my-table .el-input-group__append{position: relative; left:-2px;}.edit_container{ padding-bottom:10px; margin-bottom: 40px; }.editer{ height: 300px; }.submit_btn{ text-align: center; }
<!--创建app.css 在 static-->css创建iconfont.css在iconfont.css里面,你需要下载fonts文件夹,这里面有很多字体,大家可以在官网上下载--> @font-face {font-family: "iconfont"; src: url('../fonts/iconfont.eot?t=1492137439402'); /* IE9*/ src: url('../fonts/iconfont.eot?t=1492137439402#iefix') format('embedded-opentype'), /* IE6-IE8 */ url('../fonts/iconfont.woff?t=1492137439402') format('woff'), /* chrome, firefox */ url('../fonts/iconfont.ttf?t=1492137439402') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/ url('../fonts/iconfont.svg?t=1492137439402#iconfont') format('svg'); /* iOS 4.1- */}.iconfont { font-family:"iconfont" !important; font-size:16px; font-style:normal; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }.icon-user:before { content: "\e600"; }.icon-home1:before { content: "\e635"; }.icon-home:before { content: "\e6a1"; }.icon-setting1:before { content: "\e601"; }.icon-setting:before { content: "\e664"; }.icon-down:before { content: "\e623"; }.icon-books1:before { content: "\e67f"; }.icon-leaf:before { content: "\e645"; }.icon-users1:before { content: "\e65a"; }.icon-menuunfold:before { content: "\eacc"; }.icon-menufold:before { content: "\eacd"; }.icon-books:before { content: "\e605"; }.icon-users:before { content: "\e883"; }.icon-books2:before { content: "\e7b9"; }
样式目录结构
App.vue文件
作者:陈楠酒肆
链接:https://www.jianshu.com/p/5d2ede5c4304