This commit is contained in:
sc 2021-04-22 14:12:22 +08:00
parent 2deb78a613
commit b651e9055d
18 changed files with 275 additions and 72 deletions

BIN
public/images/avatar.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
public/images/avatar2.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

BIN
public/images/avatar3.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

View File

@ -1,34 +1,35 @@
{ {
"code": 200, "code": 200,
"data": { "data": {
"userInfo" : { "userInfo": {
"userName":"Admin" "userId": "1",
"userName": "Administrator"
}, },
"menuList" : [ "menuList": [{
{
"name": "组件", "name": "组件",
"path": "/vab", "path": "/vab",
"meta": { "meta": {
"icon":"el-icon-takeaway-box" "icon": "el-icon-takeaway-box"
}, },
"children": [ "children": []
{ },
"path": "/vab/list", {
"name": "布局",
"path": "/layout",
"meta": {
"icon": "el-icon-files"
},
"children": [{
"path": "/layout/list",
"name": "列表", "name": "列表",
"meta": {}, "meta": {},
"component": "list" "component": "list"
}, },
{ {
"path": "/vab/show", "path": "/layout/show",
"name": "详情", "name": "详情",
"meta": {}, "meta": {},
"component": "show" "component": "show"
},
{
"path": "/vab/lala",
"name": "404",
"meta": {},
"component": "lala"
} }
] ]
}, },
@ -36,14 +37,54 @@
"name": "其他", "name": "其他",
"path": "/other", "path": "/other",
"meta": { "meta": {
"icon":"el-icon-more" "icon": "el-icon-more"
}, },
"children": [ "children": [
{ {
"path": "/other/1", "path": "/link",
"name": "other1", "name": "外部链接",
"meta": {
"icon": "el-icon-link"
},
"children": [
{
"path": "https://baidu.com",
"name": "百度",
"meta": {
"target": "_blank"
}
},
{
"path": "https://www.google.cn",
"name": "谷歌",
"meta": {
"target": "_blank"
}
}
]
},
{
"path": "/iframe",
"name": "Iframe",
"meta": {
"icon": "el-icon-position"
},
"children": [
{
"path": "https://vue3js.cn/docs/zh/",
"name": "VUE 3"
},
{
"path": "https://element-plus.org?id=1",
"name": "Element Plus"
}
]
},
{
"path": "/other/lala",
"name": "404",
"meta": {}, "meta": {},
"component": "list" "component": "lala"
} }
] ]
}, },
@ -51,16 +92,14 @@
"name": "配置", "name": "配置",
"path": "/setting", "path": "/setting",
"meta": { "meta": {
"icon":"el-icon-setting" "icon": "el-icon-setting"
}, },
"children": [ "children": [{
{ "path": "/setting/1",
"path": "/setting/1", "name": "setting1",
"name": "setting1", "meta": {},
"meta": {}, "component": "lala"
"component": "lala" }]
}
]
} }
] ]
}, },

View File

@ -11,4 +11,4 @@
<style lang="less"> <style lang="less">
@import '@/style/style.less'; @import '@/style/style.less';
</style> </style>

View File

@ -1,10 +1,13 @@
<template> <template>
<label v-for="navMenu in navMenus" v-bind:key="navMenu"> <div v-if="navMenus.length<=0" style="padding:20px;">
<el-alert title="无子集菜单" center type="info" :closable="false"></el-alert>
</div>
<template v-for="navMenu in navMenus" v-bind:key="navMenu">
<el-menu-item v-if="!navMenu.children" :index="navMenu.path"> <el-menu-item v-if="!navMenu.children" :index="navMenu.path">
<a v-if="navMenu.meta&&navMenu.meta.target" :href="navMenu.path" :target="navMenu.meta.target" @click.stop='a'></a>
<i v-if="navMenu.meta&&navMenu.meta.icon" :class="navMenu.meta.icon || 'el-icon-menu'"></i> <i v-if="navMenu.meta&&navMenu.meta.icon" :class="navMenu.meta.icon || 'el-icon-menu'"></i>
<span>{{navMenu.name}}</span> <span>{{navMenu.name}}</span>
</el-menu-item> </el-menu-item>
<el-submenu v-if="navMenu.children" :index="navMenu.path"> <el-submenu v-if="navMenu.children" :index="navMenu.path">
<template #title> <template #title>
<i v-if="navMenu.meta&&navMenu.meta.icon" :class="navMenu.meta.icon || 'el-icon-menu'"></i> <i v-if="navMenu.meta&&navMenu.meta.icon" :class="navMenu.meta.icon || 'el-icon-menu'"></i>
@ -12,7 +15,7 @@
</template> </template>
<NavMenu :navMenus="navMenu.children"></NavMenu> <NavMenu :navMenus="navMenu.children"></NavMenu>
</el-submenu> </el-submenu>
</label> </template>
</template> </template>
<script> <script>
@ -22,6 +25,8 @@
data() { data() {
return {} return {}
}, },
methods: {} methods: {
a(){}
}
} }
</script> </script>

View File

@ -1,14 +1,77 @@
<template> <template>
<div class="adminui-header"> <div class="adminui-header">
header <div class="left-panel">
<el-breadcrumb separator-class="el-icon-arrow-right">
<template v-for="(item) in breadList" v-bind:key="item" >
<el-breadcrumb-item v-if="item.path !='/'"><i v-if="item.meta&&item.meta.icon" :class="item.meta.icon || 'el-icon-menu'"></i>{{item.name}}</el-breadcrumb-item>
</template>
</el-breadcrumb>
</div>
<div class="center-panel">
</div>
<div class="right-panel">
<div class="setting panel-item">
<i class="el-icon-setting"></i>
</div>
<el-popover placement="bottom" :width="300" trigger="click">
<template #reference>
<div class="msg panel-item">
<el-badge :value="1" class="badge" type="danger">
<i class="el-icon-bell"></i>
</el-badge>
</div>
</template>
<div>
<el-empty description="暂无消息"></el-empty>
</div>
</el-popover>
<el-dropdown trigger="click" @command="handleUser">
<div class="user panel-item">
<el-avatar :size="30">{{ userNameF }}</el-avatar>
<label>{{ userName }}<i class="el-icon-arrow-down el-icon--right"></i></label>
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="userInfo">个人设置</el-dropdown-item>
<el-dropdown-item divided command="outLogin">退出登录</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
props: {}, data() {
setup() { return {
breadList: [],
userName: "",
userNameF: ""
}
},
created() {
var userInfo = this.$TOOL.data.get("user").userInfo;
this.userName = userInfo.userName;
this.userNameF = this.userName.substring(0,1);
this.getBreadcrumb();
},
watch: {
$route() {
this.getBreadcrumb();
}
},
methods: {
handleUser(command) {
if(command == "outLogin"){
this.$router.replace({path: '/login'});
}
},
getBreadcrumb(){
let matched = this.$route.matched;
this.breadList = matched;
}
} }
} }
</script> </script>

View File

@ -11,7 +11,7 @@
<div class="aminui-side"> <div class="aminui-side">
<div class="adminui-side-scroll"> <div class="adminui-side-scroll">
<el-menu :default-active="$route.path" router> <el-menu :default-active="$route.fullPath" router>
<NavMenu :navMenus="nextMenu"></NavMenu> <NavMenu :navMenus="nextMenu"></NavMenu>
</el-menu> </el-menu>
</div> </div>
@ -37,7 +37,7 @@
var menu = this.$TOOL.data.get("user").menuList; var menu = this.$TOOL.data.get("user").menuList;
var home = this.$router.options.routes[0].children[0]; var home = this.$router.options.routes[0].children[0];
menu.unshift(home); menu.unshift(home);
this.menu = menu; this.menu = this.filterUrl(menu);
this.showThis() this.showThis()
}, },
setup() { setup() {
@ -51,13 +51,9 @@
methods: { methods: {
// //
showThis(){ showThis(){
var menu = this.$TOOL.data.get("user").menuList;
var home = this.$router.options.routes[0].children[0]; var home = this.$router.options.routes[0].children[0];
menu.unshift(home); this.pmenu = this.$route.matched[1] || home;
var pl = this.$route.path.split("/"); this.nextMenu = this.filterUrl(this.pmenu.children);
var p = pl.length<=2?home.path:"/" + pl[1];
this.pmenu = p==home.path ? home:this.getRoute(p, menu);
this.nextMenu = this.pmenu.children;
}, },
// //
showMenu(route) { showMenu(route) {
@ -74,6 +70,21 @@
this.getRoute(path, item.children); this.getRoute(path, item.children);
} }
} }
},
//
filterUrl(map){
var newMap = []
map.forEach(item => {
item.meta = item.meta?item.meta:{};
if(item.path.startsWith('http') && item.meta.target!='_blank'){
item.path = `/${encodeURIComponent(item.path)}`;
}
if(item.children&&item.children.length > 0){
this.filterUrl(item.children);
}
newMap.push(item)
})
return newMap;
} }
} }
} }

View File

@ -5,7 +5,7 @@
<Head></Head> <Head></Head>
<Tags></Tags> <Tags></Tags>
<div class="adminui-main"> <div class="adminui-main">
<router-view></router-view> <router-view :key="$route.fullPath"></router-view>
</div> </div>
</div> </div>

View File

@ -60,6 +60,7 @@ router.beforeEach(async (to, from, next) => {
let userInfo = tool.data.get("user"); let userInfo = tool.data.get("user");
if(to.path === "/login"){ if(to.path === "/login"){
isGetApiRouter = false;
next(); next();
return false; return false;
} }
@ -79,7 +80,7 @@ router.beforeEach(async (to, from, next) => {
}) })
router.addRoute(routes_404) router.addRoute(routes_404)
if (to.matched.length == 0) { if (to.matched.length == 0) {
router.push(to.path); router.push(to.fullPath);
} }
isGetApiRouter = true; isGetApiRouter = true;
} }
@ -94,7 +95,7 @@ router.onError((error) => {
NProgress.done(); NProgress.done();
ElNotification.error({ ElNotification.error({
title: '路由错误', title: '路由错误',
message: error message: error.message
}); });
}); });
@ -102,14 +103,22 @@ router.onError((error) => {
//转换 //转换
function filterAsyncRouter(routerMap) { function filterAsyncRouter(routerMap) {
const accessedRouters = [] const accessedRouters = []
routerMap.filter(itemRouter => { routerMap.forEach(item => {
accessedRouters.push({ item.meta = item.meta?item.meta:{};
path: itemRouter.path, //处理外部链接特殊路由
name: itemRouter.name, if(item.path.startsWith('http') && item.meta.target!='_blank'){
meta: itemRouter.meta, item.path = `/${encodeURIComponent(item.path)}`;
children: filterAsyncRouter(itemRouter.children || []), item.component = 'other/iframe';
component: loadComponent(itemRouter.component) }
}) //MAP转路由对象
var route = {
path: item.path,
name: item.name,
meta: item.meta,
children: item.children ? filterAsyncRouter(item.children) : null,
component: loadComponent(item.component)
}
accessedRouters.push(route)
}) })
return accessedRouters return accessedRouters
} }

View File

@ -1,4 +1,4 @@
#app, body, html {width: 100%;height: 100%;background-color: #f8f8f8;font-size: 12px;} #app, body, html {width: 100%;height: 100%;background-color: #f6f8f9;font-size: 12px;}
* {margin: 0;padding: 0;box-sizing: border-box;outline: none;} * {margin: 0;padding: 0;box-sizing: border-box;outline: none;}
/* 全局滚动条样式 */ /* 全局滚动条样式 */
@ -29,7 +29,23 @@
.aminui-body {position: absolute;z-index: 70;top:0px;left:275px;bottom:0px;right:0px;} .aminui-body {position: absolute;z-index: 70;top:0px;left:275px;bottom:0px;right:0px;}
.adminui-header {height: 50px;border-bottom: 1px solid #ebeef5;background: #fff;box-shadow: 0 1px 4px rgba(0,21,41,.08);} .adminui-header {height: 50px;border-bottom: 1px solid #ebeef5;background: #fff;box-shadow: 0 1px 4px rgba(0,21,41,.08);display: flex;justify-content:space-between;}
.adminui-header .left-panel {display: flex;align-items: center;padding-left:20px;}
.adminui-header .right-panel {display: flex;align-items: center;}
.adminui-header .panel-item {height:50px;line-height: 50px;padding:0 20px;cursor: pointer;}
.adminui-header .panel-item i {font-size: 16px;}
.adminui-header .panel-item .badge .el-badge__content {top:15px}
.adminui-header .panel-item:hover {background: #eee;}
.adminui-header .el-breadcrumb .el-breadcrumb__inner i {margin-right:5px;}
.adminui-header .user {display: flex;align-items: center;}
.adminui-header .user label {display: inline-block;margin-left:5px;font-size: 12px;cursor:pointer;}
.adminui-tags {height:35px;background: #fff;border-bottom: 1px solid #e6e6e6;box-shadow: 0 1px 4px rgba(0,21,41,.08);} .adminui-tags {height:35px;background: #fff;border-bottom: 1px solid #e6e6e6;box-shadow: 0 1px 4px rgba(0,21,41,.08);}
.adminui-tags li {cursor: pointer;display: inline-block;float: left;height:34px;line-height: 34px;} .adminui-tags li {cursor: pointer;display: inline-block;float: left;height:34px;line-height: 34px;}
.adminui-tags li a {display: inline-block;padding:0 10px;width:100%;height:100%;color: #999;text-decoration:none;} .adminui-tags li a {display: inline-block;padding:0 10px;width:100%;height:100%;color: #999;text-decoration:none;}
@ -40,8 +56,9 @@
.adminui-tags li.active a {color: #fff;} .adminui-tags li.active a {color: #fff;}
.adminui-main {position: absolute;top:85px;left:0px;right:0px;bottom:0px;overflow: auto;} .adminui-main {position: absolute;top:85px;left:0px;right:0px;bottom:0px;overflow: auto;padding: 20px;}
.el-menu {border: none!important;} .el-menu {border: none!important;}
.el-menu-item.is-active {background: #ecf5ff;} .el-menu-item.is-active {background: #ecf5ff;}
.el-menu .el-menu-item a {color: inherit;text-decoration: none;display: block;width:100%;height:100%;position: absolute;top:0px;left:0px;}

View File

@ -1,9 +1,44 @@
<template> <template>
<div>HOME</div> <el-row>
<el-col :span="24">
<el-card shadow="never">
<div class="welTop">
<div class="icon">
<el-avatar :size="60" src="images/avatar.jpg"></el-avatar>
</div>
<div class="main">
<h2>~ admin忙碌了一上午记得吃午饭哦</h2>
<p>最近更新动态面包屑外部链接Iframe链接等</p>
</div>
<div class="icons">
<div class="avatar-list">
<el-tooltip content="Sakuya" placement="top">
<el-avatar class="avatar" :size="30" src="images/avatar.jpg"></el-avatar>
</el-tooltip>
<el-tooltip content="Lolowan" placement="top">
<el-avatar class="avatar" :size="30" src="images/avatar2.gif"></el-avatar>
</el-tooltip>
<el-tooltip content="Ali" placement="top">
<el-avatar class="avatar" :size="30" src="images/avatar3.gif"></el-avatar>
</el-tooltip>
</div>
<p>Participants</p>
</div>
</div>
</el-card>
</el-col>
</el-row>
</template> </template>
<script> <script>
</script> </script>
<style> <style scoped>
.welTop {display: flex;}
.welTop .main {margin-left:20px;}
.welTop .main h2 {font-size: 20px;color: #3c4a54;}
.welTop .main p {color: #999;margin-top:10px;line-height: 1.8;}
.welTop .icons {margin-left:auto;text-align: center;}
.welTop .icons p {font-size: 12px;}
.avatar-list .avatar {margin-left: -10px;border: 3px solid #fff;cursor: pointer;}
</style> </style>

View File

@ -1,6 +1,7 @@
<template> <template>
<div>LIST</div> <div>
<div style="height:1800px"></div> <el-empty description="LIST"></el-empty>
</div>
</template> </template>
<script> <script>

View File

@ -17,7 +17,12 @@
login: async function() { login: async function() {
var userInfo = await this.$API.user.info(); var userInfo = await this.$API.user.info();
this.$TOOL.data.set("user", userInfo.data); this.$TOOL.data.set("user", userInfo.data);
this.$router.push({path: '/'}); this.$router.replace({path: '/'});
//
this.$notify.success({
title: '登录成功',
message: '欢迎登录'
})
} }
} }
} }

View File

@ -1,5 +1,7 @@
<template> <template>
<div>404</div> <div>
<el-empty description="404"></el-empty>
</div>
</template> </template>
<script> <script>

View File

@ -1,3 +1,3 @@
<template> <template>
<router-view></router-view> <router-view></router-view>
</template> </template>

View File

@ -0,0 +1,17 @@
<template>
<iframe :src="src" frameborder='0'></iframe>
</template>
<script>
export default {
data() {
return {
src: decodeURIComponent(this.$route.fullPath.substr(1))
}
}
}
</script>
<style scoped>
iframe {border:0;position: absolute;top:0px;left:0px;right:0px;bottom:0px;width:100%;height:100%;}
</style>

View File

@ -1,7 +1,6 @@
<template> <template>
<div>SHOW</div> <div>
<div class="main"> <el-empty description="SHOW"></el-empty>
<el-input v-model="input" placeholder="请输入内容" clearable></el-input>
</div> </div>
</template> </template>
@ -15,6 +14,6 @@
} }
</script> </script>
<style> <style scoped>
.main {width:200px;} .main {width:200px;}
</style> </style>