Commit 485ce0f5 authored by zhouzihao's avatar zhouzihao

init

parents
Pipeline #114 failed with stages
> 1%
last 2 versions
not ie <= 8
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw*
# iview-layoutui
## Project setup
```
yarn install
```
### Compiles and hot-reloads for development
```
yarn run serve
```
## Layout.vue
该组件是整个项目的框架UI,详细请查看代码。
## Master.vue
该组件是内容区域通用页面,我已经使用Slot设计好样式已经统一,你们只要往里面放相应的标题、按钮、表格、分页就好。
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).
module.exports = {
presets: [
'@vue/app'
]
}
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "iview-layoutui",
"version": "0.1.0",
"private": true,
"homepage": "http://awbeci.xyz/iview-layoutui/",
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"predeploy": "npm run build",
"deploy": "gh-pages -d dist"
},
"dependencies": {
"axios": "^0.19.2",
"iview": "^3.1.5",
"vue": "^2.5.17",
"vue-router": "^3.0.1"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.2.0",
"@vue/cli-service": "^3.2.0",
"gh-pages": "^2.0.1",
"postcss-calc": "^7.0.1",
"postcss-cssnext": "^3.1.0",
"postcss-import": "^12.0.1",
"vue-template-compiler": "^2.5.17"
}
}
module.exports = {
plugins: {
"postcss-import": {},
"postcss-cssnext": {}
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>iview-layoutui</title>
</head>
<body>
<noscript>
<strong>We're sorry but iview-layoutui doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
<template>
<div id="app">
<router-view/>
</div>
</template>
<style>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body{
width:100%;
height: 100%;
overflow: hidden;
}
*, :after, :before {
box-sizing: border-box;
}
#app {
width:100%;
height: 100%;
margin:0;
padding:0;
}
</style>
.content-wrapper {
& >>>.ivu-table th{
background-color: #0062c6 !important;
color: #fff !important;
}
/**状态前面小圆点样式*/
& >>> .red-cir {
width: 11px;
height: 11px;
display: inline-block;
background: #e74c3c;
border-radius: 50% 50%;
margin-right: 5px;
}
& >>> .green-cir {
width: 11px;
height: 11px;
display: inline-block;
background: #19be6b;
border-radius: 50% 50%;
margin-right: 5px;
}
& >>> .ivu-dropdown-item{
transition: unset !important;
&:hover {
background: #008CEE !important;
color:#fff !important;
}
}
& >>> .ivu-select-item{
transition: unset !important;
&:hover {
background: #008CEE !important;
color:#fff !important;
}
}
& >>> .ivu-select-item-focus{
background: #fff !important;
color:#008CEE !important;
font-weight:bold;
}
}
.dd-menu{
& >>> .ivu-dropdown-item{
transition: unset !important;
&:hover {
background: #008CEE !important;
color:#fff !important;
}
}
}
\ No newline at end of file
<style lang="postcss" scoped>
@import '../assets/common.pcss';
.ivu-btn-text:hover{
background-color: rgba(255, 255, 255, .2) !important;
}
.ivu-layout.ivu-layout-has-sider{
height: 100%;
}
.ivu-layout-sider{
background: #fff;
transition: none;
}
.ivu-layout-header{
height: 60px;
line-height: 60px;
}
.ivu-menu{
height: calc(100% - 60px);
overflow-y: auto;
}
.ivu-menu-item{
white-space: nowrap;
}
.ivu-menu-submenu{
white-space: nowrap;
& .ivu-menu-submenu-title{
white-space: nowrap;
}
}
.dd-menu{
width: 200px;
min-width: 200px;
height: 100%;
& .ddi-wapper{
display:flex;
align-items:center;
& .ddi-text{
padding-left:10px;
}
}
}
.admin-layout-container{
position: absolute;
width: 100%;
height: 100%;
& .layout{
background: #f5f7f9;
position: relative;
overflow: hidden;
height: 100%;
& .sidebar{
background: #fff;
}
& .dropdown-wrap{
height: 100%;
position: relative;
display: flex;
flex-direction: column;
background: #fff;
box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.2);
z-index: 11;
& .dw-content{
height: 100%;
& .dd-btn{
width: 83px;
margin-left: -5px;
padding:10px 0;
}
}
}
& .logo{
width: auto;
height: 60px;
display: flex;
text-align: center;
align-items: center;
justify-content: flex-start;
cursor: pointer;
border-bottom: 1px solid #363e4f;
position: relative;
padding-left:20px;
background: #0d58ab;
& .logo-saiqu{
display: flex;
align-items: center;
justify-content: flex-start;
position: relative;
& .user-name{
color:#fff;
font-size:16px;
margin-left:15px;
}
}
}
}
& .layout-header-bar{
background: #fff;
padding: 0;
position: relative;
display: flex;
flex-direction: column;
z-index: 20;
width:100%;
& .header-wapper{
display:flex;
align-tems:center;
justify-content:space-between;
position: relative;
z-index: 1;
box-shadow: 0 2px 1px 1px rgba(100, 100, 100, 0.1);
background: #0e64c3;
color: #fff;
& .header-left{
display:flex;
align-items:center;
& .header-title{
font-size:18px;
font-weight:bold
}
}
& .header-right{
margin-right:20px;
& .btn-blue{
color: #fff;
font-size:16px;
}
}
}
}
& .main-content{
width: 100%;
height: calc(100% - 60px);
position: relative;
overflow: auto;
& .main-layout-con{
height: 100%;
overflow: hidden;
& .content-wrapper{
overflow: auto;
padding: 10px;
position: relative;
& .spinCls{
width: 60px !important;
height: 60px !important;
&::after{
background: linear-gradient(#0d58ab, #0256ac);
}
}
}
& .tags-nav-wapper{
background: #f0f0f0;
height: 40px;
padding: 0;
& .tags-nav{
height: 100%;
width: 100%;
position: relative;
border-top: 1px solid #F0F0F0;
border-bottom: 1px solid #F0F0F0;
& .btn-con{
position: absolute;
top: 0px;
height: 100%;
background: #fff;
padding-top: 3px;
z-index: 10;
}
& button{
padding: 6px 4px;
line-height: 14px;
text-align: center;
}
& .left-btn{
left: 0px;
border-right: 1px solid #F0F0F0;
}
& .right-btn{
right: 0px;
border-left: 1px solid #F0F0F0;
}
& .scroll-outer{
position: absolute;
left: 28px;
right: 28px;
top: 0;
bottom: 0;
box-shadow: 0px 0 3px 2px rgba(100,100,100,.1) inset;
& .scroll-body{
height: calc(100% - 1px);
display: inline-block;
padding: 1px 4px 0;
position: absolute;
overflow: visible;
white-space: nowrap;
transition: left .3s ease;
.ivu-tag-dot-inner{
transition: background .2s ease;
}
}
}
& .contextmenu {
position: absolute;
margin: 0;
padding: 5px 0;
background: #fff;
z-index: 100;
list-style-type: none;
border-radius: 4px;
box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3);
& li {
margin: 0;
padding: 5px 15px;
cursor: pointer;
&:hover {
background: #eee;
}
}
}
}
}
}
}
& .layout-logo-left{
width: 90%;
height: 30px;
background: #5b6270;
border-radius: 3px;
margin: 15px auto;
}
& .menu-icon{
cursor: pointer;
transition: all .3s;
margin: 0 20px 0;
}
& .rotate-icon{
transform: rotate(-90deg);
}
& .menu-item {
position: absolute;
overflow: auto;
box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.2);
&:after{
width: 0;
}
& span{
display: inline-block;
white-space: nowrap;
vertical-align: bottom;
transition: width .2s ease .2s;
}
& i{
transform: translateX(0px);
transition: font-size .2s ease, transform .2s ease;
vertical-align: middle;
font-size: 16px;
}
}
& .collapsed-menu {
& span{
width: 0px;
transition: width .2s ease;
}
& i{
transform: translateX(5px);
transition: font-size .2s ease .2s, transform .2s ease .2s;
vertical-align: middle;
font-size: 22px;
}
}
}
</style>
<template>
<section class="admin-layout-container">
<div class="layout">
<Layout>
<Sider ref="sidebar" class="sidebar" hide-trigger collapsible width="230" :collapsed-width="78" v-model.trim="isCollapsed">
<div class="logo" >
<div class="xfind-line" v-if="!isCollapsed">
<div class="line-h"></div>
</div>
<div v-if="!isCollapsed" class="logo-saiqu">
<Avatar icon="ios-person" size="large"/>
<span class="user-name">Admin</span>
</div>
<Avatar icon="ios-person" size="large" v-else/>
</div>
<Menu
ref="side_menu"
:active-name="activeMenuName"
:open-names="openMenuName"
theme="light"
width="230px"
:class="menuitemClasses"
@on-select="choosedMenu"
v-if="!isCollapsed">
<template v-for="(menu,menu_index) in menus">
<Submenu :name="menu.name" v-if="menu.children" :key="menu_index">
<template slot="title">
<Icon :size="20" :type="menu.icon"></Icon>
<span>{{menu.title}}</span>
</template>
<MenuItem :name="child.name" v-for="(child ,child_index) in menu.children" :key="child_index">
<Icon :size="20" :type="child.icon"></Icon>
<span>{{child.title}}</span>
</MenuItem>
</Submenu>
<MenuItem :name="menu.name" v-if="!menu.children && menu.showInMenus" :key="menu_index">
<Icon :size="20" :type="menu.icon" :key="menu_index"></Icon>
<span>{{menu.title}}</span>
</MenuItem>
</template>
</Menu>
<div class="dropdown-wrap" v-if="isCollapsed">
<div class="dw-content">
<template v-for="(menu,menu_index) in menus">
<Dropdown transfer placement="right-start" v-if="menu.children" @on-click="dropdownClick" :key="menu_index">
<Button class="dd-btn" type="text">
<Icon :size="25" :type="menu.icon"></Icon>
</Button>
<DropdownMenu class="dd-menu" slot="list">
<template v-for="(child, i) in menu.children">
<DropdownItem :name="child.name" :key="i">
<div class="ddi-wapper">
<Icon :size="16" :type="child.icon"></Icon>
<span class="ddi-text">
{{ child.title }}
</span>
</div>
</DropdownItem>
</template>
</DropdownMenu>
</Dropdown>
<Dropdown transfer v-if="!menu.children && menu.showInMenus" placement="right-start" @on-click="dropdownClick" :key="menu_index">
<Button class="dd-btn" type="text">
<Icon :size="25" :type="menu.icon"></Icon>
</Button>
<DropdownMenu class="dd-menu" slot="list">
<DropdownItem :name="menu.name">
<div class="ddi-wapper">
<Icon :size="16" :type="menu.icon"></Icon>
<span class="ddi-text">
{{ menu.title }}
</span>
</div>
</DropdownItem>
</DropdownMenu>
</Dropdown>
</template>
</div>
</div>
</Sider>
<Layout>
<!-- :style="{width: isCollapsed?'calc(100% - 78px)':'calc(100% - 230px)'}" -->
<Header class="layout-header-bar">
<div class="header-wapper">
<div class="header-left">
<Icon @click.native="collapsedSider" :class="rotateIcon" type="md-menu" size="28"></Icon>
<span class="header-title">iView后台管理系统</span>
</div>
<div class="header-right">
<!-- <Button type="text" icon="person" size="large">个人中心</Button>
<Button type="text" icon="android-notifications" size="large" @click="clickNotice">消息通知</Button> -->
<!-- <Dropdown>
<a href="javascript:void(0)">
下拉菜单
<Icon type="ios-arrow-down"></Icon>
</a>
<DropdownMenu slot="list">
<DropdownItem>驴打滚</DropdownItem>
<DropdownItem>炸酱面</DropdownItem>
</DropdownMenu>
</Dropdown> -->
<Button type="text" icon="md-exit" class="btn-blue" size="large" @click="quit">退出系统</Button>
</div>
</div>
</Header>
<!-- :style="{width:isCollapsed?'calc(100% - 78px)':'calc(100% - 230px)'}" -->
<Content class="main-content">
<Layout class="main-layout-con">
<div class="tags-nav-wapper">
<div class="tags-nav">
<div class="btn-con left-btn">
<Button type="text" @click="handleScroll(240)">
<Icon :size="18" type="ios-arrow-back" />
</Button>
</div>
<div ref="scrollOuter" class="scroll-outer" @DOMMouseScroll="handlescroll" @mousewheel="handlescroll">
<div ref="scrollBody" class="scroll-body" :style="{left: tagBodyLeft + 'px'}">
<transition-group name="taglist-moving-animation">
<Tag type="dot"
v-for="tab in tags"
:closable="tab.closable"
:color="tab.choosed? 'primary':'#e9eaec'"
:name="tab.name"
@click.native="clickTag(tab)"
@on-close="closeTag"
:key="tab.name">
{{tab.title}}
</Tag>
</transition-group>
</div>
</div>
<div class="btn-con right-btn">
<Button type="text" @click="handleScroll(-240)">
<Icon :size="18" type="ios-arrow-forward" />
</Button>
</div>
</div>
</div>
<Content class="content-wrapper">
<!-- <Spin size="large" fix v-if="spinShow">
<Circle2 />
</Spin> -->
<!--保存组件状态到内存,避免重新渲染-->
<keep-alive>
<router-view/>
</keep-alive>
</Content>
</Layout>
</Content>
</Layout>
</Layout>
</div>
</section>
</template>
<script>
export default {
data(){
return{
isCollapsed: false,
// ------------------------------ 菜单操作开始 --------------------------------
title:'首页',
activeMenuName:'admin',
openMenuName:[],
tagBodyLeft: 0,
rightOffset: 40,
outerPadding: 4,
contextMenuLeft: 0,
contextMenuTop: 0,
visible: false,
menus:[
{
title:'首页',
num:1,
name:'admin',
icon:'ios-home',
href:'/home',
closable:false,
showInTags:true,
showInMenus:true,
choosed:true
},
{
title:'项目管理',
name:'projectManage',
icon:'ios-people',
children:[
{
title:'项目列表',
name:'projectList',
href:'/projectlist',
closable:true,
showInTags:false,
showInMenus:true,
choosed:false
},
]
},
{
title:'环境管理',
name:'envManage',
icon:'ios-cog',
children:[
{
title:'环境列表',
name:'envlist',
href:'/envlist',
closable:true,
showInTags:false,
showInMenus:true,
choosed:false
},
]
},
{
title:'配置管理',
name:'configMange',
icon:'ios-cash',
children:[
{
title:'配置列表',
name:'configList',
href:'/configList',
closable:true,
showInTags:false,
showInMenus:true,
choosed:false
},
]
},
{
title:'构建管理',
name:'buildManage',
icon:'ios-stats',
children:[
{
title:'构建日志列表',
name:'buildLogList',
href:'/buildLog:ist',
closable:true,
showInTags:false,
showInMenus:true,
choosed:false
},
]
},
{
title:'项目源数据',
name:'frontend-setting',
icon:'logo-html5',
href:'/metaDataList',
closable:true,
showInTags:false,
showInMenus:true,
choosed:false
},
]
// ------------------------------ 菜单操作结束 --------------------------------
}
},
computed: {
// 筛选menus中选中的menu
tags(){
let tags = [];
// 将menus中showInTags=true的标签放到tags数组中
this.menus.forEach(menu=>{
if(menu.showInTags){
tags.push(menu);
}else if(menu.children){
menu.children.forEach(child=>{
if(child.showInTags){
tags.push(child)
}
})
}
});
// console.log('tags=>',tags)
//标签数组排序,从小到到
tags.sort((a,b)=>{
return (a.num - b.num)
})
return tags;
},
rotateIcon () {
return [
'menu-icon',
this.isCollapsed ? 'rotate-icon' : ''
];
},
menuitemClasses () {
return [
'menu-item',
this.isCollapsed ? 'collapsed-menu' : ''
]
}
},
// ------------------------------ 菜单操作开始 --------------------------------
//刷新页面之后保存并选中最后一次菜单和标签
beforeRouteEnter (to, from, next) {
next(vm => {
// 通过 `vm` 访问组件实例
let activeMenuName = localStorage.activeMenuName;
vm.activeMenuName = activeMenuName;
let tags_last_num = vm.tags[vm.tags.length - 1].num;
if(activeMenuName && activeMenuName.length != 0){
vm.menus.forEach(_menu=>{
if(activeMenuName == _menu.name){
_menu.choosed = true;
_menu.showInTags = true;
_menu.num = tags_last_num + 1;
}
else if(_menu.children){
_menu.children.forEach(child=>{
if(activeMenuName == child.name){
child.choosed = true;
child.showInTags = true;
child.num = tags_last_num + 1;
vm.openMenuName = [_menu.name];
}
})
}
else{
// 排除首页
if(_menu.name != 'admin'){
_menu.choosed = false;
_menu.showInTags = false;
}else{
_menu.choosed = false;
}
}
})
}
vm.$nextTick(()=>{
// console.log(vm.$refs.side_menu, 22)
// vm.$refs.side_menu.updateOpened();
// vm.$refs.side_menu.updateActiveName();
});
})
},
// ------------------------------ 菜单操作结束 --------------------------------
methods: {
/*tags 滚动事件 */
handlescroll (e) {
var type = e.type
let delta = 0
if (type === 'DOMMouseScroll' || type === 'mousewheel') {
delta = (e.wheelDelta) ? e.wheelDelta : -(e.detail || 0) * 40
}
this.handleScroll(delta)
},
/*tags 滑动事件 */
handleScroll (offset) {
const outerWidth = this.$refs.scrollOuter.offsetWidth
const bodyWidth = this.$refs.scrollBody.offsetWidth
if (offset > 0) {
this.tagBodyLeft = Math.min(0, this.tagBodyLeft + offset)
} else {
if (outerWidth < bodyWidth) {
if (this.tagBodyLeft < -(bodyWidth - outerWidth)) {
this.tagBodyLeft = this.tagBodyLeft
} else {
this.tagBodyLeft = Math.max(this.tagBodyLeft + offset, outerWidth - bodyWidth)
}
} else {
this.tagBodyLeft = 0
}
}
},
quit(){
this.$router.push('/login')
},
clickNotice(){
this.choosedMenu('notice');
},
collapsedSider() {
this.$refs.sidebar.toggleCollapse();
},
// ------------------------------ 菜单操作开始 --------------------------------
closeTag(event, name){
// 判断该标签是否是选中状态
// 如果是那么就要设置标签数组中最后一个标签成选中状态
// 如果否那么就直接删除就好
let is_choosed = false;
this.menus.forEach((menu)=>{
if(menu.name == name){
is_choosed = menu.choosed;
menu.showInTags = false;
}else if(menu.children){
menu.children.forEach(child=>{
if(child.name == name){
is_choosed = child.choosed;
child.showInTags = false;
}
})
}
})
// 关闭标签并选中tags中最后一个标签高亮
if(is_choosed){
let last_tag = this.tags[this.tags.length-1];
last_tag.choosed = true;
this.$router.push(last_tag.href);
this.activeMenuName = last_tag.name;
localStorage.activeMenuName = this.activeMenuName;
}
},
clickTag(tag){
this.tags.forEach(_tag=>{
if(_tag.name == tag.name){
_tag.choosed=true;
}else{
_tag.choosed= false;
}
})
// 设置菜单选中name
this.activeMenuName = tag.name;
localStorage.activeMenuName = this.activeMenuName;
// 刷新菜单
this.$nextTick(()=>{
if(this.$refs.side_menu){
this.$refs.side_menu.updateActiveName()
}
});
//点击tab跳转
this.$router.push(`${tag.href}`);
},
choosedMenu(name){
// 获取标签数组最后一个元素的num
let tags_last_num = this.tags[this.tags.length - 1].num;
// 设置选中菜单name
this.activeMenuName = name;
localStorage.activeMenuName = this.activeMenuName;
//根据name查找对应的菜单对象
let menu = null;
this.menus.forEach(_menu=>{
if(_menu.name == name){
// 只有不在tags数组中的元素才能设置num
if(!_menu.showInTags){
_menu.num = tags_last_num + 1;
}
menu = _menu;
_menu.showInTags = true;
_menu.choosed = true;
}
else if(_menu.children){
_menu.children.forEach(child=>{
if(child.name == name){
// 只有不在tags数组中的元素才能设置num
if(!_menu.showInTags){
child.num = tags_last_num + 1;
}
menu = child;
child.showInTags = true;
child.choosed = true;
}else{
child.choosed = false;
}
})
}
else {
_menu.choosed = false;
}
})
this.$router.push(`${menu.href}`);
},
dropdownClick(name){
this.choosedMenu(name);
}
// ------------------------------ 菜单操作结束 --------------------------------
}
}
</script>
<style lang="postcss" scoped>
.master-page-container{
background-color: #fff;
box-shadow: 0 4px 5px 0 rgba(0, 0, 0, .14), 0 1px 10px 0 rgba(0, 0, 0, .12), 0 2px 4px -1px rgba(0, 0, 0, .2);
& .master-page-wrap{
& .title-header{
display: flex;
align-items: center;
justify-content: space-between;
padding:10px 15px;
border-bottom: 1px solid #dddee1;
& .title-content{
display: flex;
align-items: center;
& .title-icon{
display: flex;
align-items: center;
margin-right:5px;
}
& p.title{
font-size: 14px;
font-weight: bold;
}
}
& .title-toolbar{
}
}
& .master-page-search-content{
padding: 15px;
padding-bottom: 0;
}
& .master-page-content-toolbar{
padding: 15px;
padding-bottom: 0;
display: flex;
align-items: center;
justify-content: space-between;
& .bar-search{
&.input-search{
width:350px;
}
}
& .bar-group{
}
}
& .master-page-padding-content{
padding:15px;
background: #fff;
padding-bottom: 0;
}
& .master-page-nopadding-content{
padding-bottom: 0;
background: #fff;
padding-left: 18px;
}
& .page-wrapper{
padding:15px;
display: flex;
width: 100%;
justify-content: flex-end;
}
}
}
</style>
<template>
<section class="master-page-container">
<div class="master-page-wrap">
<div class="title-header" v-if="title">
<div class="title-content">
<div class="title-icon">
<slot name="title-icon"></slot>
</div>
<p class="title">{{title}}</p>
</div>
<div class="title-toolbar">
<slot name="title-toolbar"></slot>
</div>
</div>
<div class="master-page-search-content" v-if="$slots.searchContent">
<slot name="searchContent"></slot>
</div>
<div class="master-page-content-toolbar" v-if="$slots.search || $slots.btns">
<div class="bar-search">
<slot name="search"></slot>
</div>
<div class="bar-group">
<slot name="btns"></slot>
</div>
</div>
<!--$slots.content表示$slots里面是否存在content内容,就是说这里的占位符可填充了内容-->
<div class="master-page-padding-content" v-if="$slots.paddingContent">
<slot name="paddingContent"></slot>
</div>
<div class="master-page-nopadding-content" v-if="$slots.content">
<slot name="content"></slot>
</div>
<div class="page-wrapper">
<slot name="pager"/>
</div>
</div>
</section>
</template>
<script>
export default {
data(){
return{
}
},
props:{
title:{
type:String
}
},
mounted(){
console.log('paddingContent=',this.$slots)
},
methods:{
}
}
</script>
const serve_url = "http://127.0.0.1:3000"
export default {
serve_url,
}
\ No newline at end of file
import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = false
import iView from 'iview';
import 'iview/dist/styles/iview.css';
Vue.use(iView);
new Vue({
router,
render: h => h(App)
}).$mount('#app')
import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'
Vue.use(Router)
export default new Router({
// mode: 'history',
routes: [
{
path: '/',
name: 'home',
component: () => import('@/components/Layout'),
children: [
{
path: '',
name: 'home',
component: () => import('@/views/Home')
},
{
path: '/home',
name: 'home2',
component: () => import('@/views/Home')
},
//项目列表
{
path: 'projectlist',
name: 'projectlist',
component: () => import('@/views/ProjectList')
},
// 环境列表
// 配置列表
// 构建日志列表
// 源数据
]
},
// 这个有什么用???
{
path: '/login',
name: 'login',
meta: {
title: '登录',
},
component: () => import('@/views/Login')
},
]
})
<template>
<div class="about">
<h1>This is an about page</h1>
</div>
</template>
<template>
<div>
<h1>Welcome</h1>
</div>
</template>
\ No newline at end of file
<style lang="postcss" scoped>
.login-container{
display:flex;
align-items: center;
justify-content: center;
width: 100%;
height: calc(100%);
& .bg-wrap{
width: 100%;
height: 100%;
background-size: cover;
background-position: center;
position: relative;
}
& .card-wrap{
position: absolute;
right:100px;
top:200px;
}
& .icon-cls{
font-weight:bold;
width:20px;
font-size:18px;
}
}
</style>
<template>
<section class="login-container">
<div class="bg-wrap" :style="{backgroundImage:`url(${login_img})`}">
<div class="card-wrap">
<Card style="width:350px" :dis-hover="true">
<p slot="title">
<Icon type="log-in"></Icon>
欢迎登录
</p>
<Form ref="userForm" :model="userForm" :rules="ruleCustom">
<FormItem prop="username">
<Input v-model.trim="userForm.username" placeholder="请输入" size="large">
<Icon type="ios-person-outline" slot="prepend" class="icon-cls"></Icon>
</Input>
</FormItem>
<FormItem prop="password">
<Input type="password" v-model.trim="userForm.password" placeholder="请输入密码" size="large">
<Icon type="ios-lock-outline" slot="prepend" class="icon-cls"></Icon>
</Input>
</FormItem>
<FormItem>
<Button type="primary" @click="btn_login()" long :loading="login_loading">登录</Button>
</FormItem>
</Form>
</Card>
</div>
</div>
</section>
</template>
<script>
export default {
data(){
return {
login_loading:false,
login_img:require("@/assets/login-bg.jpg"),
userForm:{
username:'',
password:''
},
ruleCustom: {
username: [
{ required: true, message: '用户名不能为空', trigger: 'blur' }
],
password: [
{ required: true, message: '密码不能为空', trigger: 'blur' }
]
}
}
},
methods:{
btn_login(){
this.$router.push('/')
}
}
}
</script>
<style lang="postcss" scoped>
.home-container {
}
.demo-drawer-footer {
width: 100%;
position: absolute;
bottom: 0;
left: 0;
border-top: 1px solid #e8e8e8;
padding: 10px 16px;
text-align: right;
background: #fff;
}
</style>
<template>
<section class="home-container">
<MasterPage title="项目列表">
<div slot="title-icon">
<Icon type="ios-game-controller-b" />
</div>
<div slot="title-toolbar">
<!-- <Button type="primary" icon="md-add" @click="">新增</Button> -->
</div>
<div slot="searchContent" class="search-content-slot">
<!-- 表单位置 -->
</div>
<div slot="search">
<Button type="info" icon="ios-search" @click="getList">查询</Button>
</div>
<div slot="btns">
<Button type="primary" icon="md-add" @click="addShow">添加</Button>
</div>
<div slot="paddingContent">
<Table :columns="columns1" :data="data1"></Table>
</div>
<div slot="pager">
<Page :total="total" :current="page" :page-size="pageSize" @on-change="pageChange" />
</div>
</MasterPage>
<Drawer title="项目详情" :closable="false" v-model="isShow" width="720">
<div>
<Form :model="showData" label-position="left" :label-width="100">
<FormItem label="项目名称">
<Input v-model="showData.name"></Input>
</FormItem>
<FormItem label="项目git地址">
<Input v-model="showData.source_git_url"></Input>
</FormItem>
<FormItem label="项目描述">
<Input v-model="showData.description"></Input>
</FormItem>
<FormItem label="项目类型">
<Input v-model="showData.type"></Input>
</FormItem>
<FormItem label="项目版本">
<Input v-model="showData.version"></Input>
</FormItem>
<FormItem label="项目源数据">
<Input v-model="showData.meta_data" type="textarea" :autosize="true"></Input>
</FormItem>
</Form>
</div>
<div class="demo-drawer-footer">
<Button style="margin-right: 8px" @click="isShow= false">取消</Button>
<Button type="primary" @click="save">保存</Button>
</div>
</Drawer>
</section>
</template>
<script>
import MasterPage from "@/components/Master";
import axios from "axios";
import config from "@/config/configs"
export default {
components: {
MasterPage
},
data() {
return {
columns1: [
{
title: "项目id",
key: "p_id",
width: 100,
fixed: "left"
},
{
title: "git地址",
key: "source_git_url",
width: 300
},
{
title: "项目名称",
key: "name",
width: 300
},
{
title: "项目描述",
key: "description",
width: 300
},
{
title: "项目版本",
key: "version",
width: 100
},
{
title: "项目类型",
key: "type",
width: 100
},
{
title: "项目数据",
key: "meta_data",
width: 300
},
{
title: "操作",
key: "action",
fixed: "right",
width: 150,
render: (h, params) => {
return h("div", [
h(
"Button",
{
props: {
type: "primary",
size: "small"
},
style: {
marginRight: "5px"
},
on: {
click: () => {
this.show(params.index);
}
}
},
"显示"
),
h(
"Button",
{
props: {
type: "primary",
size: "small"
}
},
"build"
)
]);
}
}
],
data1: [],
page: 1,
pageSize: 10,
total: 0,
isShow: false,
isAdd: false,
showData: {}
};
},
methods: {
getList: function() {
axios
.get(
config.serve_url+"/project/page?page=" +
this.page +
"&pageSize=" +
this.pageSize
)
.then(rs => {
if (rs.status == 200) {
this.data1 = rs.data.data;
this.total = rs.data.paged.total;
}
})
.catch(err => {
console.log(JSON.stringify(err));
});
},
addShow: function() {
this.isShow = true;
this.showData = {};
},
show: function(index) {
this.isShow = true;
this.showData = this.data1[index];
},
build: function() {
//
},
save: function() {
//保存或者新建
this.isShow = false;
axios
.post( config.serve_url+"/project/", this.showData)
.then(res => {
this.$Message.success("操作成功");
this.getList();
})
.catch(err => {
this.$Message.error(err);
});
},
pageChange: function(i) {
this.page = i;
this.getList();
}
},
mounted: function() {
this.getList();
}
};
</script>
\ No newline at end of file
module.exports = {
baseUrl: 'iview-layoutui'
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment