commit
a61779b7dc
33
README.md
33
README.md
|
@ -16,7 +16,9 @@
|
|||
## 功能 ##
|
||||
- [x] Element UI
|
||||
- [x] 登录/注销
|
||||
- [x] Dashboard
|
||||
- [x] 表格
|
||||
- [x] Tab选项卡
|
||||
- [x] 表单
|
||||
- [x] 图表 :bar_chart:
|
||||
- [x] 富文本编辑器
|
||||
|
@ -24,6 +26,8 @@
|
|||
- [x] 图片拖拽/裁剪上传
|
||||
- [x] 支持切换主题色 :sparkles:
|
||||
- [x] 列表拖拽排序
|
||||
- [x] 权限测试
|
||||
- [x] 404 / 403
|
||||
|
||||
|
||||
## 目录结构介绍 ##
|
||||
|
@ -37,18 +41,20 @@
|
|||
| |-- Header.vue // 公共头部
|
||||
| |-- Home.vue // 公共路由入口
|
||||
| |-- Sidebar.vue // 公共左边栏
|
||||
| |-- page // 主要路由页面
|
||||
| |-- Tags.vue // 页面切换标签组件
|
||||
| |-- page // 主要路由页面
|
||||
| |-- 403.vue
|
||||
| |-- 404.vue
|
||||
| |-- BaseCharts.vue // 基础图表
|
||||
| |-- BaseForm.vue // 基础表单
|
||||
| |-- BaseTable.vue // 基础表格
|
||||
| |-- DashBoard.vue // 系统首页
|
||||
| |-- DragList.vue // 拖拽列表组件
|
||||
| |-- Login.vue // 登录
|
||||
| |-- Markdown.vue // markdown组件
|
||||
| |-- Premission.vue // 权限测试组件
|
||||
| |-- Readme.vue // 自述组件
|
||||
| |-- Upload.vue // 图片上传
|
||||
| |-- VueEditor.vue // 富文本编辑器
|
||||
| |-- VueTable.vue // datasource表格组件
|
||||
| |-- App.vue // 页面入口文件
|
||||
| |-- main.js // 程序入口文件,加载各种公共组件
|
||||
|-- .babelrc // ES6语法编译配置
|
||||
|
@ -124,9 +130,6 @@ vue.js封装sChart.js的图表组件。访问地址:[vue-schart](https://githu
|
|||
### element-ui ###
|
||||
一套基于vue.js2.0的桌面组件库。访问地址:[element](http://element.eleme.io/#/zh-CN/component/layout)
|
||||
|
||||
### vue-datasource ###
|
||||
一个用于动态创建表格的vue.js服务端组件。访问地址:[vue-datasource](https://github.com/coderdiaz/vue-datasource)
|
||||
|
||||
### Vue-Quill-Editor ###
|
||||
基于Quill、适用于Vue2的富文本编辑器。访问地址:[vue-quill-editor](https://github.com/surmon-china/vue-quill-editor)
|
||||
|
||||
|
@ -141,28 +144,32 @@ vue.js封装sChart.js的图表组件。访问地址:[vue-schart](https://githu
|
|||
## 其他注意事项 ##
|
||||
### 一、如果我不想用到上面的某些组件呢,那我怎么在模板中删除掉不影响到其他功能呢? ###
|
||||
|
||||
举个栗子,我不想用 vue-datasource 这个组件,那我需要分四步走。
|
||||
举个栗子,我不想用 Vue-Quill-Editor 这个组件,那我需要分四步走。
|
||||
|
||||
第一步:删除该组件的路由,在目录 src/router/index.js 中,找到引入改组件的路由,删除下面这段代码。
|
||||
|
||||
```JavaScript
|
||||
{
|
||||
path: '/vuetable',
|
||||
component: resolve => require(['../components/page/VueTable.vue'], resolve) // vue-datasource组件
|
||||
// 富文本编辑器组件
|
||||
path: '/editor',
|
||||
component: resolve => require(['../components/page/VueEditor.vue'], resolve)
|
||||
},
|
||||
```
|
||||
|
||||
第二步:删除引入该组件的文件。在目录 src/components/page/ 删除 VueTable.vue 文件。
|
||||
第二步:删除引入该组件的文件。在目录 src/components/page/ 删除 VueEditor.vue 文件。
|
||||
|
||||
第三步:删除该页面的入口。在目录 src/components/common/Sidebar.vue 中,找到该入口,删除下面这段代码。
|
||||
|
||||
```HTML
|
||||
<el-menu-item index="vuetable">Vue表格组件</el-menu-item>
|
||||
```js
|
||||
{
|
||||
index: 'editor',
|
||||
title: '富文本编辑器'
|
||||
},
|
||||
```
|
||||
|
||||
第四步:卸载该组件。执行以下命令:
|
||||
|
||||
npm un vue-datasource -S
|
||||
npm un vue-quill-editor -S
|
||||
|
||||
完成。
|
||||
|
||||
|
|
32
README_EN.md
32
README_EN.md
|
@ -10,7 +10,9 @@ The scheme as a set of multi-function background frame templates, suitable for m
|
|||
## Function ##
|
||||
- [x] Element-UI
|
||||
- [x] Login/Logout
|
||||
- [x] Dashboard
|
||||
- [x] Table
|
||||
- [x] Tabs
|
||||
- [x] From
|
||||
- [x] Chart :bar_chart:
|
||||
- [x] Editor
|
||||
|
@ -18,6 +20,8 @@ The scheme as a set of multi-function background frame templates, suitable for m
|
|||
- [x] Upload pictures by clipping or dragging
|
||||
- [x] Support manual switch themes :sparkles:
|
||||
- [x] List drag sort
|
||||
- [x] Permission
|
||||
- [x] 404 / 403
|
||||
|
||||
|
||||
## Directory structure ##
|
||||
|
@ -31,18 +35,20 @@ The scheme as a set of multi-function background frame templates, suitable for m
|
|||
| |-- Header.vue // Header component
|
||||
| |-- Home.vue // Home component
|
||||
| |-- Sidebar.vue // Sidebar component
|
||||
| |-- page // Router page
|
||||
| |-- Tags.vue
|
||||
| |-- page // Router page
|
||||
| |-- 403.vue
|
||||
| |-- 404.vue
|
||||
| |-- BaseCharts.vue // BaseCharts
|
||||
| |-- BaseForm.vue // BaseForm
|
||||
| |-- BaseTable.vue // BaseTable
|
||||
| |-- Login.vue // Login
|
||||
| |-- Dashboard.vue
|
||||
| |-- DragList.vue
|
||||
| |-- Markdown.vue // Markdown
|
||||
| |-- Premission.vue
|
||||
| |-- Readme.vue // Readme
|
||||
| |-- Upload.vue // Upload
|
||||
| |-- VueEditor.vue // VueEditor
|
||||
| |-- VueTable.vue // VueTable
|
||||
| |-- App.vue // Main component
|
||||
| |-- main.js // Entry file
|
||||
|-- .babelrc // ES6 syntax compiler configuration
|
||||
|
@ -117,9 +123,6 @@ Vue.js wrapper for sChart.js. Github : [vue-schart](https://github.com/linxin/vu
|
|||
### element-ui ###
|
||||
A desktop component library based on vue.js2.0 . Github : [element](http://element.eleme.io/#/zh-CN/component/layout)
|
||||
|
||||
### vue-datasource ###
|
||||
A Vue.js server side component to create dynamic tables. Github : [vue-datasource](https://github.com/coderdiaz/vue-datasource)
|
||||
|
||||
### Vue-Quill-Editor ###
|
||||
Quill editor component for Vue2. Github : [vue-quill-editor](https://github.com/surmon-china/vue-quill-editor)
|
||||
|
||||
|
@ -133,28 +136,31 @@ A Vue wrapper component for cropperjs. Github: [vue-cropperjs](https://github.co
|
|||
## Notice ##
|
||||
### 一、If I don't want to use some components, how can I delete it? ###
|
||||
|
||||
For example, I don't want to use the vue-datasource component, I need to take four steps.
|
||||
For example, I don't want to use the Vue-Quill-Editor component, I need to take four steps.
|
||||
|
||||
The first step to remove the component of the routing. Enter 'src/router/index.js' and delete the code below.
|
||||
|
||||
```JavaScript
|
||||
{
|
||||
path: '/vuetable',
|
||||
component: resolve => require(['../components/page/VueTable.vue'], resolve)
|
||||
path: '/editor',
|
||||
component: resolve => require(['../components/page/VueEditor.vue'], resolve)
|
||||
},
|
||||
```
|
||||
|
||||
Second,delete the component files. Enter 'src/components/page/' and delete 'VueTable.vue' file.
|
||||
Second,delete the component files. Enter 'src/components/page/' and delete 'VueEditor.vue' file.
|
||||
|
||||
The third step is to delete the entry. Enter 'src/components/common/Sidebar.vue' and delete the code below.
|
||||
|
||||
```HTML
|
||||
<el-menu-item index="vuetable">Vue表格组件</el-menu-item>
|
||||
```js
|
||||
{
|
||||
index: 'editor',
|
||||
title: '富文本编辑器'
|
||||
},
|
||||
```
|
||||
|
||||
Finally, uninstall this component.
|
||||
|
||||
npm un vue-datasource -S
|
||||
npm un vue-quill-editor -S
|
||||
|
||||
Complete!
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 914 B |
|
@ -2,9 +2,9 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>vue-manage-system | 基于Vue 的后台管理系统</title>
|
||||
<title>vue-manage-system | 基于Vue的后台管理系统</title>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
|
||||
<meta name="keywords" content="vue.js, wms, vue2, 后台模板, 管理系统, element" />
|
||||
<meta name="keywords" content="vue, vue-manage-system, manage-system, 后台, 管理系统, element" />
|
||||
<meta name="description" content="基于Vue2 + Element UI 的后台管理系统解决方案" />
|
||||
</head>
|
||||
<body>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "vue-manage-system",
|
||||
"version": "3.0.0",
|
||||
"version": "3.1.0",
|
||||
"description": "基于Vue.js 2.x系列 + element-ui 内容管理系统解决方案",
|
||||
"author": "lin-xin <2981207131@qq.com>",
|
||||
"private": true,
|
||||
|
@ -13,10 +13,9 @@
|
|||
"axios": "^0.15.3",
|
||||
"babel-polyfill": "^6.23.0",
|
||||
"element-ui": "2.3.3",
|
||||
"mavon-editor": "^2.5.2",
|
||||
"mavon-editor": "^2.5.4",
|
||||
"vue": "^2.5.16",
|
||||
"vue-cropperjs": "^2.2.0",
|
||||
"vue-datasource": "1.0.12",
|
||||
"vue-quill-editor": "3.0.6",
|
||||
"vue-router": "^3.0.1",
|
||||
"vue-schart": "^0.1.4",
|
||||
|
@ -31,7 +30,6 @@
|
|||
"babel-plugin-transform-runtime": "^6.22.0",
|
||||
"babel-plugin-transform-vue-jsx": "^3.5.0",
|
||||
"babel-preset-env": "^1.3.2",
|
||||
"babel-preset-es2015": "^6.24.1",
|
||||
"babel-preset-stage-2": "^6.22.0",
|
||||
"chalk": "^2.0.1",
|
||||
"copy-webpack-plugin": "^4.0.1",
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 16 KiB |
Binary file not shown.
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
@ -1,19 +1,45 @@
|
|||
<template>
|
||||
<div class="header">
|
||||
<!-- 折叠按钮 -->
|
||||
<div class="collapse-btn" @click="collapseChage">
|
||||
<i class="el-icon-menu"></i>
|
||||
</div>
|
||||
<div class="logo">后台管理系统</div>
|
||||
<div class="user-info">
|
||||
<el-dropdown trigger="click" @command="handleCommand">
|
||||
<span class="el-dropdown-link">
|
||||
<img class="user-logo" src="../../../static/img/img.jpg">
|
||||
{{username}}
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="loginout">退出登录</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<div class="header-right">
|
||||
<div class="header-user-con">
|
||||
<!-- 全屏显示 -->
|
||||
<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="static/img/img.jpg"></div>
|
||||
<!-- 用户名下拉菜单 -->
|
||||
<el-dropdown class="user-name" trigger="click" @command="handleCommand">
|
||||
<span class="el-dropdown-link">
|
||||
{{username}} <i class="el-icon-caret-bottom"></i>
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<a href="http://blog.gdfengshuo.com/about/" target="_blank">
|
||||
<el-dropdown-item>关于作者</el-dropdown-item>
|
||||
</a>
|
||||
<a href="https://github.com/lin-xin/vue-manage-system" target="_blank">
|
||||
<el-dropdown-item>项目仓库</el-dropdown-item>
|
||||
</a>
|
||||
<el-dropdown-item divided command="loginout">退出登录</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -23,7 +49,9 @@
|
|||
data() {
|
||||
return {
|
||||
collapse: false,
|
||||
name: 'linxin'
|
||||
fullscreen: false,
|
||||
name: 'linxin',
|
||||
message: 2
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
|
@ -33,15 +61,44 @@
|
|||
}
|
||||
},
|
||||
methods:{
|
||||
// 用户名下拉菜单选择事件
|
||||
handleCommand(command) {
|
||||
if(command == 'loginout'){
|
||||
localStorage.removeItem('ms_username')
|
||||
this.$router.push('/login');
|
||||
}
|
||||
},
|
||||
// 侧边栏折叠
|
||||
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) {
|
||||
// IE11
|
||||
element.msRequestFullscreen();
|
||||
}
|
||||
}
|
||||
this.fullscreen = !this.fullscreen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -53,44 +110,70 @@
|
|||
width: 100%;
|
||||
height: 70px;
|
||||
font-size: 22px;
|
||||
line-height: 70px;
|
||||
color: #fff;
|
||||
}
|
||||
.collapse-btn{
|
||||
float: left;
|
||||
padding: 0 21px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.collapse-btn:hover{
|
||||
background: rgb(40,52,70);
|
||||
line-height: 70px;
|
||||
}
|
||||
.header .logo{
|
||||
float: left;
|
||||
width:250px;
|
||||
/* text-align: center; */
|
||||
line-height: 70px;
|
||||
}
|
||||
.user-info {
|
||||
.header-right{
|
||||
float: right;
|
||||
padding-right: 50px;
|
||||
font-size: 16px;
|
||||
color: #fff;
|
||||
}
|
||||
.user-info .el-dropdown-link{
|
||||
.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;
|
||||
display: inline-block;
|
||||
padding-left: 50px;
|
||||
color: #fff;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
text-align: center;
|
||||
border-radius: 15px;
|
||||
cursor: pointer;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.user-info .user-logo{
|
||||
.btn-bell-badge{
|
||||
position: absolute;
|
||||
left:0;
|
||||
top:15px;
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -2,8 +2,15 @@
|
|||
<div class="wrapper">
|
||||
<v-head></v-head>
|
||||
<v-sidebar></v-sidebar>
|
||||
<div class="content" :class="{'content-collapse':collapse}">
|
||||
<transition name="move" mode="out-in"><router-view></router-view></transition>
|
||||
<div class="content-box" :class="{'content-collapse':collapse}">
|
||||
<v-tags></v-tags>
|
||||
<div class="content">
|
||||
<transition name="move" mode="out-in">
|
||||
<keep-alive>
|
||||
<router-view></router-view>
|
||||
</keep-alive>
|
||||
</transition>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -11,6 +18,7 @@
|
|||
<script>
|
||||
import vHead from './Header.vue';
|
||||
import vSidebar from './Sidebar.vue';
|
||||
import vTags from './Tags.vue';
|
||||
import bus from '../common/bus';
|
||||
export default {
|
||||
data(){
|
||||
|
@ -19,7 +27,7 @@
|
|||
}
|
||||
},
|
||||
components:{
|
||||
vHead, vSidebar
|
||||
vHead, vSidebar, vTags
|
||||
},
|
||||
created(){
|
||||
bus.$on('collapse', msg => {
|
||||
|
|
|
@ -32,23 +32,18 @@
|
|||
items: [
|
||||
{
|
||||
icon: 'el-icon-setting',
|
||||
index: 'readme',
|
||||
title: '自述文件'
|
||||
index: 'dashboard',
|
||||
title: '系统首页'
|
||||
},
|
||||
{
|
||||
icon: 'el-icon-tickets',
|
||||
index: '2',
|
||||
title: '常用表格',
|
||||
subs: [
|
||||
{
|
||||
index: 'table',
|
||||
title: '基础表格'
|
||||
},
|
||||
{
|
||||
index: 'datasource',
|
||||
title: 'datasource表格'
|
||||
}
|
||||
]
|
||||
index: 'table',
|
||||
title: '基础表格'
|
||||
},
|
||||
{
|
||||
icon: 'el-icon-message',
|
||||
index: 'tabs',
|
||||
title: 'tab选项卡'
|
||||
},
|
||||
{
|
||||
icon: 'el-icon-date',
|
||||
|
@ -87,6 +82,11 @@
|
|||
icon: 'el-icon-warning',
|
||||
index: 'permission',
|
||||
title: '权限测试'
|
||||
},
|
||||
{
|
||||
icon: 'el-icon-error',
|
||||
index: '404',
|
||||
title: '404页面'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
<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 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="mini" type="primary">
|
||||
标签选项<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-dropdown-menu size="small" 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>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
tagsList: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
isActive(path) {
|
||||
return path === this.$route.path;
|
||||
},
|
||||
// 关闭单个标签
|
||||
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.path && this.$router.push(item.path);
|
||||
}else{
|
||||
this.$router.push('/');
|
||||
}
|
||||
},
|
||||
// 关闭全部标签
|
||||
closeAll(){
|
||||
this.tagsList = [];
|
||||
this.$router.push('/');
|
||||
},
|
||||
// 关闭其他标签
|
||||
closeOther(){
|
||||
const curItem = this.tagsList.filter(item => {
|
||||
return item.path === this.$route.path;
|
||||
})
|
||||
this.tagsList = curItem;
|
||||
},
|
||||
// 设置标签
|
||||
setTags(route){
|
||||
const isExist = this.tagsList.some(item => {
|
||||
return item.path === route.path;
|
||||
})
|
||||
!isExist && this.tagsList.push({
|
||||
title: route.meta.title,
|
||||
path: route.path
|
||||
})
|
||||
},
|
||||
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>
|
||||
.tags {
|
||||
position: relative;
|
||||
height: 30px;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
padding-right: 120px;
|
||||
}
|
||||
|
||||
.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: 23px;
|
||||
line-height: 23px;
|
||||
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: 30px;
|
||||
background: #fff;
|
||||
box-shadow: -3px 0 15px 3px rgba(0, 0, 0, .1);
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -0,0 +1,56 @@
|
|||
<template>
|
||||
<div class="error-page">
|
||||
<div class="error-code">4<span>0</span>3</div>
|
||||
<div class="error-desc">啊哦~ 你没有权限访问该页面哦</div>
|
||||
<div class="error-handle">
|
||||
<router-link to="/">
|
||||
<el-button type="primary" size="large">返回首页</el-button>
|
||||
</router-link>
|
||||
<el-button class="error-btn" type="primary" size="large" @click="goBack">返回上一页</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
goBack(){
|
||||
this.$router.go(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped>
|
||||
.error-page{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #f3f3f3;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.error-code{
|
||||
line-height: 1;
|
||||
font-size: 250px;
|
||||
font-weight: bolder;
|
||||
color: #f02d2d;
|
||||
}
|
||||
.error-code span{
|
||||
color: #00a854;
|
||||
}
|
||||
.error-desc{
|
||||
font-size: 30px;
|
||||
color: #777;
|
||||
}
|
||||
.error-handle{
|
||||
margin-top: 30px;
|
||||
padding-bottom: 200px;
|
||||
}
|
||||
.error-btn{
|
||||
margin-left: 100px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,56 @@
|
|||
<template>
|
||||
<div class="error-page">
|
||||
<div class="error-code">4<span>0</span>4</div>
|
||||
<div class="error-desc">啊哦~ 你所访问的页面不存在</div>
|
||||
<div class="error-handle">
|
||||
<router-link to="/">
|
||||
<el-button type="primary" size="large">返回首页</el-button>
|
||||
</router-link>
|
||||
<el-button class="error-btn" type="primary" size="large" @click="goBack">返回上一页</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
goBack(){
|
||||
this.$router.go(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped>
|
||||
.error-page{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #f3f3f3;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.error-code{
|
||||
line-height: 1;
|
||||
font-size: 250px;
|
||||
font-weight: bolder;
|
||||
color: #2d8cf0;
|
||||
}
|
||||
.error-code span{
|
||||
color: #00a854;
|
||||
}
|
||||
.error-desc{
|
||||
font-size: 30px;
|
||||
color: #777;
|
||||
}
|
||||
.error-handle{
|
||||
margin-top: 30px;
|
||||
padding-bottom: 200px;
|
||||
}
|
||||
.error-btn{
|
||||
margin-left: 100px;
|
||||
}
|
||||
</style>
|
|
@ -2,8 +2,7 @@
|
|||
<div class="table">
|
||||
<div class="crumbs">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item><i class="el-icon-tickets"></i> 表格</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>基础表格</el-breadcrumb-item>
|
||||
<el-breadcrumb-item><i class="el-icon-tickets"></i> 基础表格</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
<div class="container">
|
||||
|
@ -26,21 +25,45 @@
|
|||
</el-table-column>
|
||||
<el-table-column label="操作" width="180">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="small"
|
||||
@click="handleEdit(scope.$index, scope.row)">编辑</el-button>
|
||||
<el-button size="small" type="danger"
|
||||
@click="handleDelete(scope.$index, scope.row)">删除</el-button>
|
||||
<el-button size="small" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
|
||||
<el-button size="small" type="danger" @click="handleDelete(scope.$index, scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="pagination">
|
||||
<el-pagination
|
||||
@current-change ="handleCurrentChange"
|
||||
layout="prev, pager, next"
|
||||
:total="1000">
|
||||
<el-pagination @current-change="handleCurrentChange" layout="prev, pager, next" :total="1000">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 编辑弹出框 -->
|
||||
<el-dialog title="编辑" :visible.sync="editVisible" width="30%">
|
||||
<el-form ref="form" :model="form" label-width="50px">
|
||||
<el-form-item label="日期">
|
||||
<el-date-picker type="date" placeholder="选择日期" v-model="form.date" value-format="yyyy-MM-dd" style="width: 100%;"></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名">
|
||||
<el-input v-model="form.name"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="地址">
|
||||
<el-input v-model="form.address"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="editVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="saveEdit">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 删除提示框 -->
|
||||
<el-dialog title="提示" :visible.sync="delVisible" width="300px" center>
|
||||
<div class="del-dialog-cnt">删除不可恢复,是否确定删除?</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="delVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="deleteRow">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -55,27 +78,35 @@
|
|||
select_cate: '',
|
||||
select_word: '',
|
||||
del_list: [],
|
||||
is_search: false
|
||||
is_search: false,
|
||||
editVisible: false,
|
||||
delVisible: false,
|
||||
form: {
|
||||
name: '',
|
||||
date: '',
|
||||
address: ''
|
||||
},
|
||||
idx: -1
|
||||
}
|
||||
},
|
||||
created(){
|
||||
created() {
|
||||
this.getData();
|
||||
},
|
||||
computed: {
|
||||
data(){
|
||||
data() {
|
||||
return this.tableData.filter((d) => {
|
||||
let is_del = false;
|
||||
for (let i = 0; i < this.del_list.length; i++) {
|
||||
if(d.name === this.del_list[i].name){
|
||||
if (d.name === this.del_list[i].name) {
|
||||
is_del = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!is_del){
|
||||
if(d.address.indexOf(this.select_cate) > -1 &&
|
||||
if (!is_del) {
|
||||
if (d.address.indexOf(this.select_cate) > -1 &&
|
||||
(d.name.indexOf(this.select_word) > -1 ||
|
||||
d.address.indexOf(this.select_word) > -1)
|
||||
){
|
||||
d.address.indexOf(this.select_word) > -1)
|
||||
) {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
|
@ -84,21 +115,23 @@
|
|||
},
|
||||
methods: {
|
||||
// 分页导航
|
||||
handleCurrentChange(val){
|
||||
handleCurrentChange(val) {
|
||||
this.cur_page = val;
|
||||
this.getData();
|
||||
},
|
||||
// 获取 easy-mock 的模拟数据
|
||||
getData(){
|
||||
getData() {
|
||||
// 开发环境使用 easy-mock 数据,正式环境使用 json 文件
|
||||
if(process.env.NODE_ENV === 'development'){
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
this.url = '/ms/table/list';
|
||||
};
|
||||
this.$axios.post(this.url, {page:this.cur_page}).then((res) => {
|
||||
this.$axios.post(this.url, {
|
||||
page: this.cur_page
|
||||
}).then((res) => {
|
||||
this.tableData = res.data.list;
|
||||
})
|
||||
},
|
||||
search(){
|
||||
search() {
|
||||
this.is_search = true;
|
||||
},
|
||||
formatter(row, column) {
|
||||
|
@ -108,37 +141,64 @@
|
|||
return row.tag === value;
|
||||
},
|
||||
handleEdit(index, row) {
|
||||
this.$message('编辑第'+(index+1)+'行');
|
||||
this.idx = index;
|
||||
const item = this.tableData[index];
|
||||
this.form = {
|
||||
name: item.name,
|
||||
date: item.date,
|
||||
address: item.address
|
||||
}
|
||||
this.editVisible = true;
|
||||
},
|
||||
handleDelete(index, row) {
|
||||
this.$message.error('删除第'+(index+1)+'行');
|
||||
this.idx = index;
|
||||
this.delVisible = true;
|
||||
},
|
||||
delAll(){
|
||||
delAll() {
|
||||
const length = this.multipleSelection.length;
|
||||
let str = '';
|
||||
this.del_list = this.del_list.concat(this.multipleSelection);
|
||||
for (let i = 0; i < length; i++) {
|
||||
str += this.multipleSelection[i].name + ' ';
|
||||
}
|
||||
this.$message.error('删除了'+str);
|
||||
this.$message.error('删除了' + str);
|
||||
this.multipleSelection = [];
|
||||
},
|
||||
handleSelectionChange(val) {
|
||||
this.multipleSelection = val;
|
||||
},
|
||||
// 保存编辑
|
||||
saveEdit() {
|
||||
this.$set(this.tableData, this.idx, this.form);
|
||||
this.editVisible = false;
|
||||
this.$message.success(`修改第 ${this.idx+1} 行成功`);
|
||||
},
|
||||
// 确定删除
|
||||
deleteRow(){
|
||||
this.tableData.splice(this.idx, 1);
|
||||
this.$message.success('删除成功');
|
||||
this.delVisible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.handle-box{
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.handle-select{
|
||||
width: 120px;
|
||||
}
|
||||
.handle-input{
|
||||
width: 300px;
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
.handle-box {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.handle-select {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.handle-input {
|
||||
width: 300px;
|
||||
display: inline-block;
|
||||
}
|
||||
.del-dialog-cnt{
|
||||
font-size: 16px;
|
||||
text-align: center
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -0,0 +1,247 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-card shadow="hover" class="mgb20">
|
||||
<div class="user-info">
|
||||
<img src="static/img/img.jpg" class="user-avator" alt="">
|
||||
<div class="user-info-cont">
|
||||
<div class="user-info-name">{{name}}</div>
|
||||
<div>{{role}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-info-list">上次登录时间:<span>2018-01-01</span></div>
|
||||
<div class="user-info-list">上次登录地点:<span>东莞</span></div>
|
||||
</el-card>
|
||||
<el-card shadow="hover">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>语言详情</span>
|
||||
</div>
|
||||
Vue
|
||||
<el-progress :percentage="57.2" color="#42b983"></el-progress>
|
||||
JavaScript
|
||||
<el-progress :percentage="29.8" color="#f1e05a"></el-progress>
|
||||
CSS
|
||||
<el-progress :percentage="11.9"></el-progress>
|
||||
HTML
|
||||
<el-progress :percentage="1.1" color="#f56c6c"></el-progress>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
<el-col :span="16">
|
||||
<el-row :gutter="20" class="mgb20">
|
||||
<el-col :span="8">
|
||||
<el-card shadow="hover" :body-style="{padding: '0px'}">
|
||||
<div class="grid-content grid-con-1">
|
||||
<i class="el-icon-view grid-con-icon"></i>
|
||||
<div class="grid-cont-right">
|
||||
<div class="grid-num">1234</div>
|
||||
<div>用户访问量</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-card shadow="hover" :body-style="{padding: '0px'}">
|
||||
<div class="grid-content grid-con-2">
|
||||
<i class="el-icon-message grid-con-icon"></i>
|
||||
<div class="grid-cont-right">
|
||||
<div class="grid-num">321</div>
|
||||
<div>系统消息</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-card shadow="hover" :body-style="{padding: '0px'}">
|
||||
<div class="grid-content grid-con-3">
|
||||
<i class="el-icon-goods grid-con-icon"></i>
|
||||
<div class="grid-cont-right">
|
||||
<div class="grid-num">5000</div>
|
||||
<div>数量</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-card shadow="hover" :body-style="{ height: '304px'}">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>待办事项</span>
|
||||
<el-button style="float: right; padding: 3px 0" type="text">添加</el-button>
|
||||
</div>
|
||||
<el-table :data="todoList" :show-header="false" height="304" style="width: 100%;font-size:14px;">
|
||||
<el-table-column width="40">
|
||||
<template slot-scope="scope">
|
||||
<el-checkbox v-model="scope.row.status"></el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column>
|
||||
<template slot-scope="scope">
|
||||
<div class="todo-item" :class="{'todo-item-del': scope.row.status}">{{scope.row.title}}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="60">
|
||||
<template slot-scope="scope">
|
||||
<i class="el-icon-edit"></i>
|
||||
<i class="el-icon-delete"></i>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
name: localStorage.getItem('ms_username'),
|
||||
todoList: [
|
||||
{
|
||||
title: '今天要修复100个bug',
|
||||
status: false,
|
||||
},
|
||||
{
|
||||
title: '今天要修复100个bug',
|
||||
status: false,
|
||||
},
|
||||
{
|
||||
title: '今天要写100行代码加几个bug吧',
|
||||
status: false,
|
||||
}, {
|
||||
title: '今天要修复100个bug',
|
||||
status: false,
|
||||
},
|
||||
{
|
||||
title: '今天要修复100个bug',
|
||||
status: true,
|
||||
},
|
||||
{
|
||||
title: '今天要写100行代码加几个bug吧',
|
||||
status: true,
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
role() {
|
||||
return this.name === 'admin' ? '超级管理员' : '普通用户';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped>
|
||||
.el-row {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.grid-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.grid-cont-right {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.grid-num {
|
||||
font-size: 30px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.grid-con-icon {
|
||||
font-size: 50px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
text-align: center;
|
||||
line-height: 100px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.grid-con-1 .grid-con-icon {
|
||||
background: rgb(45, 140, 240);
|
||||
}
|
||||
|
||||
.grid-con-1 .grid-num {
|
||||
color: rgb(45, 140, 240);
|
||||
}
|
||||
|
||||
.grid-con-2 .grid-con-icon {
|
||||
background: rgb(100, 213, 114);
|
||||
}
|
||||
|
||||
.grid-con-2 .grid-num {
|
||||
color: rgb(45, 140, 240);
|
||||
}
|
||||
|
||||
.grid-con-3 .grid-con-icon {
|
||||
background: rgb(242, 94, 67);
|
||||
}
|
||||
|
||||
.grid-con-3 .grid-num {
|
||||
color: rgb(242, 94, 67);
|
||||
}
|
||||
|
||||
.user-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-bottom: 20px;
|
||||
border-bottom: 2px solid #ccc;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.user-avator {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.user-info-cont {
|
||||
padding-left: 50px;
|
||||
flex: 1;
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.user-info-cont div:first-child {
|
||||
font-size: 30px;
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.user-info-list {
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
.user-info-list span {
|
||||
margin-left: 70px;
|
||||
}
|
||||
|
||||
.mgb20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.todo-item {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.todo-item-del {
|
||||
text-decoration: line-through;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -41,7 +41,7 @@
|
|||
this.$refs[formName].validate((valid) => {
|
||||
if (valid) {
|
||||
localStorage.setItem('ms_username',this.ruleForm.username);
|
||||
this.$router.push('/readme');
|
||||
this.$router.push('/');
|
||||
} else {
|
||||
console.log('error submit!!');
|
||||
return false;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<div class="crumbs">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item><i class="el-icon-date"></i> 表单</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>markdown</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>markdown编辑器</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
<div class="container">
|
||||
|
@ -20,8 +20,6 @@
|
|||
<script>
|
||||
import { mavonEditor } from 'mavon-editor'
|
||||
import 'mavon-editor/dist/css/index.css'
|
||||
// 重写mavon的flex样式来兼容IE
|
||||
import 'static/css/mavon-flex.css'
|
||||
export default {
|
||||
data: function(){
|
||||
return {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
</div>
|
||||
<div class="container">
|
||||
<h1>管理员权限页面</h1>
|
||||
<p>只有用 admin 账号登录的才拥有管理员权限,才能进到这个页面,其他账号想进来都会跳到登录页面,重新用管理员账号登录才有权限。</p>
|
||||
<p>只有用 admin 账号登录的才拥有管理员权限,才能进到这个页面,其他账号想进来都会跳到403页面,重新用管理员账号登录才有权限。</p>
|
||||
<p>想尝试一下,请<router-link to="/login" class="logout">退出登录</router-link>,随便输入个账号名,再进来试试看。</p>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,88 +0,0 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="crumbs">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item><i class="el-icon-setting"></i> 自述</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
<div class="ms-doc">
|
||||
<h3>README.md</h3>
|
||||
<article>
|
||||
<h1>manage-system</h1>
|
||||
<p>基于Vue.js 2.x系列 + Element UI 的后台管理系统解决方案</p>
|
||||
<h2>前言</h2>
|
||||
<p>之前在公司用了Vue + Element组件库做了个后台管理系统,基本很多组件可以直接引用组件库的,但是也有一些需求无法满足。像图片裁剪上传、富文本编辑器、图表等这些在后台管理系统中很常见的功能,就需要引用其他的组件才能完成。从寻找组件,到使用组件的过程中,遇到了很多问题,也积累了宝贵的经验。所以我就把开发这个后台管理系统的经验,总结成这个后台管理系统解决方案。</p>
|
||||
<p>该方案作为一套多功能的后台框架模板,适用于绝大部分的后台管理系统(Web Management System)开发。基于vue.js,使用vue-cli脚手架快速生成项目目录,引用Element UI组件库,方便开发快速简洁好看的组件。分离颜色样式,支持手动切换主题色,而且很方便使用自定义主题色。</p>
|
||||
<h2>功能</h2>
|
||||
<el-checkbox disabled checked>Element UI</el-checkbox>
|
||||
<br>
|
||||
<el-checkbox disabled checked>登录/注销</el-checkbox>
|
||||
<br>
|
||||
<el-checkbox disabled checked>表格</el-checkbox>
|
||||
<br>
|
||||
<el-checkbox disabled checked>表单</el-checkbox>
|
||||
<br>
|
||||
<el-checkbox disabled checked>图表</el-checkbox>
|
||||
<br>
|
||||
<el-checkbox disabled checked>富文本编辑器</el-checkbox>
|
||||
<br>
|
||||
<el-checkbox disabled checked>markdown编辑器</el-checkbox>
|
||||
<br>
|
||||
<el-checkbox disabled checked>图片拖拽/裁剪上传</el-checkbox>
|
||||
<br>
|
||||
<el-checkbox disabled checked>支持切换主题色</el-checkbox>
|
||||
<br>
|
||||
<el-checkbox disabled checked>列表拖拽排序</el-checkbox>
|
||||
<br>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.ms-doc{
|
||||
width:100%;
|
||||
max-width: 980px;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
.ms-doc h3{
|
||||
padding: 9px 10px 10px;
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
line-height: 17px;
|
||||
background-color: #f5f5f5;
|
||||
border: 1px solid #d8d8d8;
|
||||
border-bottom: 0;
|
||||
border-radius: 3px 3px 0 0;
|
||||
}
|
||||
.ms-doc article{
|
||||
padding: 45px;
|
||||
word-wrap: break-word;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ddd;
|
||||
border-bottom-right-radius: 3px;
|
||||
border-bottom-left-radius: 3px;
|
||||
}
|
||||
.ms-doc article h1{
|
||||
font-size:32px;
|
||||
padding-bottom: 10px;
|
||||
margin-bottom: 15px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
.ms-doc article h2 {
|
||||
margin: 24px 0 16px;
|
||||
font-weight: 600;
|
||||
line-height: 1.25;
|
||||
padding-bottom: 7px;
|
||||
font-size: 24px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
.ms-doc article p{
|
||||
margin-bottom: 15px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.ms-doc article .el-checkbox{
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,128 @@
|
|||
<template>
|
||||
<div class="">
|
||||
<div class="crumbs">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item><i class="el-icon-message"></i> tab选项卡</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
<div class="container">
|
||||
<el-tabs v-model="message">
|
||||
<el-tab-pane :label="`未读消息(${unread.length})`" name="first">
|
||||
<el-table :data="unread" :show-header="false" style="width: 100%">
|
||||
<el-table-column>
|
||||
<template slot-scope="scope">
|
||||
<span class="message-title">{{scope.row.title}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="date" width="180"></el-table-column>
|
||||
<el-table-column width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="small" @click="handleRead(scope.$index)">标为已读</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="handle-row">
|
||||
<el-button type="primary">全部标为已读</el-button>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="`已读消息(${read.length})`" name="second">
|
||||
<template v-if="message === 'second'">
|
||||
<el-table :data="read" :show-header="false" style="width: 100%">
|
||||
<el-table-column>
|
||||
<template slot-scope="scope">
|
||||
<span class="message-title">{{scope.row.title}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="date" width="150"></el-table-column>
|
||||
<el-table-column width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="danger" @click="handleDel(scope.$index)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="handle-row">
|
||||
<el-button type="danger">删除全部</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="`回收站(${recycle.length})`" name="third">
|
||||
<template v-if="message === 'third'">
|
||||
<el-table :data="recycle" :show-header="false" style="width: 100%">
|
||||
<el-table-column>
|
||||
<template slot-scope="scope">
|
||||
<span class="message-title">{{scope.row.title}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="date" width="150"></el-table-column>
|
||||
<el-table-column width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-button @click="handleRestore(scope.$index)">还原</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="handle-row">
|
||||
<el-button type="danger">清空回收站</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
message: 'first',
|
||||
showHeader: false,
|
||||
unread: [{
|
||||
date: '2018-04-19 20:00:00',
|
||||
title: '【系统通知】该系统将于今晚凌晨2点到5点进行升级维护',
|
||||
},{
|
||||
date: '2018-04-19 21:00:00',
|
||||
title: '今晚12点整发大红包,先到先得',
|
||||
}],
|
||||
read: [{
|
||||
date: '2018-04-19 20:00:00',
|
||||
title: '【系统通知】该系统将于今晚凌晨2点到5点进行升级维护'
|
||||
}],
|
||||
recycle: [{
|
||||
date: '2018-04-19 20:00:00',
|
||||
title: '【系统通知】该系统将于今晚凌晨2点到5点进行升级维护'
|
||||
}]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleRead(index) {
|
||||
const item = this.unread.splice(index, 1);
|
||||
console.log(item);
|
||||
this.read = item.concat(this.read);
|
||||
},
|
||||
handleDel(index) {
|
||||
const item = this.read.splice(index, 1);
|
||||
this.recycle = item.concat(this.recycle);
|
||||
},
|
||||
handleRestore(index) {
|
||||
const item = this.recycle.splice(index, 1);
|
||||
this.read = item.concat(this.read);
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
unreadNum(){
|
||||
return this.unread.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.message-title{
|
||||
cursor: pointer;
|
||||
}
|
||||
.handle-row{
|
||||
margin-top: 30px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
<template>
|
||||
<div class="table">
|
||||
<div class="crumbs">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item><i class="el-icon-tickets"></i> 表格</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>VueDatasource</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="plugins-tips">
|
||||
vue-datasource:一个用于动态创建表格的vue.js服务端组件。
|
||||
访问地址:<a href="https://github.com/coderdiaz/vue-datasource" target="_blank">vue-datasource</a>
|
||||
</div>
|
||||
<datasource language="en" :table-data="getData" :columns="columns" :pagination="information.pagination"
|
||||
:actions="actions"
|
||||
v-on:change="changePage"
|
||||
v-on:searching="onSearch"
|
||||
></datasource>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from 'axios';
|
||||
import Datasource from 'vue-datasource';
|
||||
export default {
|
||||
data(){
|
||||
return {
|
||||
url: './static/datasource.json',
|
||||
information: {
|
||||
pagination:{},
|
||||
data:[]
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
name: 'Id',
|
||||
key: 'id',
|
||||
},
|
||||
{
|
||||
name: 'Name',
|
||||
key: 'name',
|
||||
},
|
||||
{
|
||||
name: 'email',
|
||||
key: 'email',
|
||||
},
|
||||
{
|
||||
name: 'ip',
|
||||
key: 'ip',
|
||||
}
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
text: 'Click',
|
||||
class: 'btn-primary',
|
||||
event: (e, row)=>{
|
||||
row && this.$message('选中的行数: ' + row.row.id);
|
||||
}
|
||||
}
|
||||
],
|
||||
query:''
|
||||
}
|
||||
},
|
||||
components: {
|
||||
Datasource
|
||||
},
|
||||
methods: {
|
||||
changePage(values) {
|
||||
this.information.pagination.per_page = values.perpage;
|
||||
this.information.data = this.information.data;
|
||||
},
|
||||
onSearch(searchQuery) {
|
||||
this.query = searchQuery;
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
getData(){
|
||||
return this.information.data.filter((d) =>{
|
||||
if(d.name.indexOf(this.query) > -1){
|
||||
return d;
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
beforeMount(){
|
||||
// 开发环境使用 easy-mock 数据,正式环境使用 json 文件
|
||||
if(process.env.NODE_ENV === 'development'){
|
||||
this.url = '/ms/table/source';
|
||||
};
|
||||
axios.get(this.url).then( (res) => {
|
||||
this.information = res.data;
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style src="../../../static/css/datasource.css"></style>
|
|
@ -12,10 +12,12 @@ Vue.prototype.$axios = axios;
|
|||
|
||||
//使用钩子函数对路由进行权限跳转
|
||||
router.beforeEach((to, from, next) => {
|
||||
if(to.meta.permission){
|
||||
const role = localStorage.getItem('ms_username');
|
||||
const role = localStorage.getItem('ms_username');
|
||||
if(!role && to.path !== '/login'){
|
||||
next('/login');
|
||||
}else if(to.meta.permission){
|
||||
// 如果是管理员权限则可进入,这里只是简单的模拟管理员权限而已
|
||||
role === 'admin' ? next() : next('/login');
|
||||
role === 'admin' ? next() : next('/403');
|
||||
}else{
|
||||
// 简单的判断IE10及以下不进入富文本编辑器,该组件不兼容
|
||||
if(navigator.userAgent.indexOf('MSIE') > -1 && to.path === '/editor'){
|
||||
|
|
|
@ -7,59 +7,68 @@ export default new Router({
|
|||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
redirect: '/login'
|
||||
redirect: '/dashboard'
|
||||
},
|
||||
{
|
||||
path: '/readme',
|
||||
path: '/',
|
||||
component: resolve => require(['../components/common/Home.vue'], resolve),
|
||||
meta: { title: '自述文件' },
|
||||
children:[
|
||||
{
|
||||
path: '/',
|
||||
component: resolve => require(['../components/page/Readme.vue'], resolve)
|
||||
path: '/dashboard',
|
||||
component: resolve => require(['../components/page/Dashboard.vue'], resolve),
|
||||
meta: { title: '系统首页' }
|
||||
},
|
||||
{
|
||||
path: '/table',
|
||||
component: resolve => require(['../components/page/BaseTable.vue'], resolve)
|
||||
component: resolve => require(['../components/page/BaseTable.vue'], resolve),
|
||||
meta: { title: '基础表格' }
|
||||
},
|
||||
{
|
||||
// vue-datasource组件
|
||||
path: '/datasource',
|
||||
component: resolve => require(['../components/page/VueTable.vue'], resolve)
|
||||
path: '/tabs',
|
||||
component: resolve => require(['../components/page/Tabs.vue'], resolve),
|
||||
meta: { title: 'tab选项卡' }
|
||||
},
|
||||
{
|
||||
path: '/form',
|
||||
component: resolve => require(['../components/page/BaseForm.vue'], resolve)
|
||||
component: resolve => require(['../components/page/BaseForm.vue'], resolve),
|
||||
meta: { title: '基本表单' }
|
||||
},
|
||||
{
|
||||
// 富文本编辑器组件
|
||||
path: '/editor',
|
||||
component: resolve => require(['../components/page/VueEditor.vue'], resolve)
|
||||
component: resolve => require(['../components/page/VueEditor.vue'], resolve),
|
||||
meta: { title: '富文本编辑器' }
|
||||
},
|
||||
{
|
||||
// markdown组件
|
||||
path: '/markdown',
|
||||
component: resolve => require(['../components/page/Markdown.vue'], resolve)
|
||||
component: resolve => require(['../components/page/Markdown.vue'], resolve),
|
||||
meta: { title: 'markdown编辑器' }
|
||||
},
|
||||
{
|
||||
// 图片上传组件
|
||||
path: '/upload',
|
||||
component: resolve => require(['../components/page/Upload.vue'], resolve)
|
||||
component: resolve => require(['../components/page/Upload.vue'], resolve),
|
||||
meta: { title: '文件上传' }
|
||||
},
|
||||
{
|
||||
// vue-schart组件
|
||||
path: '/charts',
|
||||
component: resolve => require(['../components/page/BaseCharts.vue'], resolve)
|
||||
component: resolve => require(['../components/page/BaseCharts.vue'], resolve),
|
||||
meta: { title: 'schart图表' }
|
||||
},
|
||||
{
|
||||
// 拖拽列表组件
|
||||
path: '/drag',
|
||||
component: resolve => require(['../components/page/DragList.vue'], resolve)
|
||||
component: resolve => require(['../components/page/DragList.vue'], resolve),
|
||||
meta: { title: '拖拽列表' }
|
||||
},
|
||||
{
|
||||
// 权限页面
|
||||
path: '/permission',
|
||||
component: resolve => require(['../components/page/Permission.vue'], resolve),
|
||||
meta: {permission: true}
|
||||
meta: { title: '权限测试', permission: true }
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -67,5 +76,17 @@ export default new Router({
|
|||
path: '/login',
|
||||
component: resolve => require(['../components/page/Login.vue'], resolve)
|
||||
},
|
||||
{
|
||||
path: '/404',
|
||||
component: resolve => require(['../components/page/404.vue'], resolve)
|
||||
},
|
||||
{
|
||||
path: '/403',
|
||||
component: resolve => require(['../components/page/403.vue'], resolve)
|
||||
},
|
||||
{
|
||||
path: '*',
|
||||
redirect: '/404'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
|
|
@ -1,18 +1,28 @@
|
|||
.header{
|
||||
background-color: #242f42;
|
||||
}
|
||||
.login-wrap{
|
||||
background: #324157;
|
||||
}
|
||||
.plugins-tips{
|
||||
background: #eef1f6;
|
||||
}
|
||||
.plugins-tips a{
|
||||
color: #20a0ff;
|
||||
}
|
||||
.el-upload--text em {
|
||||
color: #20a0ff;
|
||||
}
|
||||
.pure-button{
|
||||
background: #20a0ff;
|
||||
.header{
|
||||
background-color: #242f42;
|
||||
}
|
||||
.login-wrap{
|
||||
background: #324157;
|
||||
}
|
||||
.plugins-tips{
|
||||
background: #eef1f6;
|
||||
}
|
||||
.plugins-tips a{
|
||||
color: #20a0ff;
|
||||
}
|
||||
.el-upload--text em {
|
||||
color: #20a0ff;
|
||||
}
|
||||
.pure-button{
|
||||
background: #20a0ff;
|
||||
}
|
||||
.tags-li.active {
|
||||
border: 1px solid #409EFF;
|
||||
background-color: #409EFF;
|
||||
}
|
||||
.message-title{
|
||||
color: #20a0ff;
|
||||
}
|
||||
.collapse-btn:hover{
|
||||
background: rgb(40,52,70);
|
||||
}
|
|
@ -1,167 +0,0 @@
|
|||
.vue-datasource *{
|
||||
box-sizing: border-box;
|
||||
font-size: 14px;
|
||||
}
|
||||
.vue-datasource .panel {
|
||||
margin-bottom: 22px;
|
||||
background-color: #fff;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
.vue-datasource .panel-default {
|
||||
border-color: #d3e0e9;
|
||||
}
|
||||
.vue-datasource .panel-heading {
|
||||
padding: 10px 15px;
|
||||
border-bottom: 1px solid transparent;
|
||||
border-top-right-radius: 3px;
|
||||
border-top-left-radius: 3px;
|
||||
}
|
||||
.vue-datasource .panel-default > .panel-heading {
|
||||
height:56px;
|
||||
color: #333333;
|
||||
background-color: #fff;
|
||||
border-color: #d3e0e9;
|
||||
}
|
||||
.vue-datasource .pull-left {
|
||||
float: left !important;
|
||||
}
|
||||
.vue-datasource .pull-right {
|
||||
float: right !important;
|
||||
}
|
||||
.vue-datasource .form-group {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.vue-datasource label {
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
margin-bottom: 5px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.vue-datasource .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
padding: 6px 12px;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
color: #555555;
|
||||
background-color: #fff;
|
||||
background-image: none;
|
||||
border: 1px solid #ccd0d2;
|
||||
border-radius: 4px;
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||
-webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
|
||||
transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
|
||||
}
|
||||
.vue-datasource .btn {
|
||||
display: inline-block;
|
||||
margin-bottom: 0;
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
touch-action: manipulation;
|
||||
cursor: pointer;
|
||||
background-image: none;
|
||||
border: 1px solid transparent;
|
||||
white-space: nowrap;
|
||||
padding: 6px 12px;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
border-radius: 4px;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.vue-datasource .btn-primary {
|
||||
color: #fff;
|
||||
background-color: #3097D1;
|
||||
border-color: #2a88bd;
|
||||
}
|
||||
.vue-datasource .table {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
margin-bottom: 22px;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
text-align: center;
|
||||
}
|
||||
.vue-datasource .table > thead > tr > th {
|
||||
vertical-align: bottom;
|
||||
border-bottom: 2px solid #ddd;
|
||||
}
|
||||
.vue-datasource .table th ,.vue-datasource .table td {
|
||||
padding: 8px;
|
||||
line-height: 1.6;
|
||||
vertical-align: top;
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
.vue-datasource .table-striped > tbody > tr:nth-of-type(odd) {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
.vue-datasource .success th ,.vue-datasource .success td{
|
||||
background-color: #dff0d8;
|
||||
}
|
||||
.vue-datasource .pagination {
|
||||
display: inline-block;
|
||||
padding-left: 0;
|
||||
margin: 22px 0;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.vue-datasource .pagination > li {
|
||||
display: inline;
|
||||
}
|
||||
.pagination > li > a,.pagination > li > span {
|
||||
position: relative;
|
||||
float: left;
|
||||
padding: 6px 12px;
|
||||
line-height: 1.6;
|
||||
text-decoration: none;
|
||||
color: #3097D1;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ddd;
|
||||
margin-left: -1px;
|
||||
}
|
||||
.pagination > .disabled > span, .pagination > .disabled > span:hover, .pagination > .disabled > span:focus, .pagination > .disabled > a, .pagination > .disabled > a:hover, .pagination > .disabled > a:focus {
|
||||
color: #777777;
|
||||
background-color: #fff;
|
||||
border-color: #ddd;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.pagination > .active > a, .pagination > .active > a:hover, .pagination > .active > a:focus, .pagination > .active > span, .pagination > .active > span:hover, .pagination > .active > span:focus {
|
||||
z-index: 3;
|
||||
color: #fff;
|
||||
background-color: #3097D1;
|
||||
border-color: #3097D1;
|
||||
cursor: default;
|
||||
}
|
||||
.vue-datasource .pagination > li:first-child > a, .vue-datasource .pagination > li:first-child > span {
|
||||
margin-left: 0;
|
||||
border-bottom-left-radius: 4px;
|
||||
border-top-left-radius: 4px;
|
||||
}
|
||||
.vue-datasource .text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@media (min-width: 768px){
|
||||
.form-inline .form-group {
|
||||
display: inline-block;
|
||||
margin-bottom: 0;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.form-inline .control-label {
|
||||
margin-bottom: 0;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.form-inline .form-control {
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
|
@ -1,94 +1,123 @@
|
|||
*{margin:0;padding:0;}
|
||||
html,body,#app,.wrapper{
|
||||
width:100%;
|
||||
height:100%;
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
html,
|
||||
body,
|
||||
#app,
|
||||
.wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
body{
|
||||
font-family:'PingFang SC', "Helvetica Neue",Helvetica, "microsoft yahei", arial, STHeiTi, sans-serif;
|
||||
|
||||
body {
|
||||
font-family: 'PingFang SC', "Helvetica Neue", Helvetica, "microsoft yahei", arial, STHeiTi, sans-serif;
|
||||
}
|
||||
a{text-decoration: none}
|
||||
.content{
|
||||
background: none repeat scroll 0 0 #f0f0f0;
|
||||
|
||||
a {
|
||||
text-decoration: none
|
||||
}
|
||||
|
||||
.content-box {
|
||||
position: absolute;
|
||||
left: 250px;
|
||||
right: 0;
|
||||
top: 70px;
|
||||
bottom:0;
|
||||
width: auto;
|
||||
padding:40px;
|
||||
box-sizing: border-box;
|
||||
bottom: 0;
|
||||
overflow-y: scroll;
|
||||
-webkit-transition: left .3s ease-in-out;
|
||||
transition: left .3s ease-in-out;
|
||||
background: #f0f0f0;
|
||||
}
|
||||
.content-collapse{
|
||||
|
||||
.content {
|
||||
width: auto;
|
||||
padding: 40px;
|
||||
}
|
||||
|
||||
.content-collapse {
|
||||
left: 65px;
|
||||
}
|
||||
.container{
|
||||
|
||||
.container {
|
||||
padding: 30px;
|
||||
background: #fff;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.crumbs{
|
||||
|
||||
.crumbs {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.pagination{
|
||||
|
||||
.pagination {
|
||||
margin: 20px 0;
|
||||
text-align: right;
|
||||
}
|
||||
.plugins-tips{
|
||||
padding:20px 10px;
|
||||
|
||||
.plugins-tips {
|
||||
padding: 20px 10px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.el-button+.el-tooltip {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.el-table tr:hover{
|
||||
.el-table tr:hover {
|
||||
background: #f6faff;
|
||||
}
|
||||
.mgb20{
|
||||
|
||||
.mgb20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.move-enter-active,.move-leave-active{
|
||||
.move-enter-active,
|
||||
.move-leave-active {
|
||||
transition: opacity .5s;
|
||||
}
|
||||
.move-enter,.move-leave{
|
||||
|
||||
.move-enter,
|
||||
.move-leave {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/*BaseForm*/
|
||||
.form-box{
|
||||
width:600px;
|
||||
|
||||
.form-box {
|
||||
width: 600px;
|
||||
}
|
||||
.form-box .line{
|
||||
|
||||
.form-box .line {
|
||||
text-align: center;
|
||||
}
|
||||
.el-time-panel__content::after, .el-time-panel__content::before {
|
||||
|
||||
.el-time-panel__content::after,
|
||||
.el-time-panel__content::before {
|
||||
margin-top: -7px;
|
||||
}
|
||||
.el-time-spinner__wrapper .el-scrollbar__wrap:not(.el-scrollbar__wrap--hidden-default){
|
||||
|
||||
.el-time-spinner__wrapper .el-scrollbar__wrap:not(.el-scrollbar__wrap--hidden-default) {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
/*Readme*/
|
||||
.ms-doc .el-checkbox__input.is-disabled+.el-checkbox__label{
|
||||
color: #333;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/*Upload*/
|
||||
.pure-button{
|
||||
width:150px;
|
||||
height:40px;
|
||||
|
||||
.pure-button {
|
||||
width: 150px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.g-core-image-corp-container .info-aside{
|
||||
height:45px;
|
||||
|
||||
.g-core-image-corp-container .info-aside {
|
||||
height: 45px;
|
||||
}
|
||||
|
||||
.el-upload--text {
|
||||
background-color: #fff;
|
||||
border: 1px dashed #d9d9d9;
|
||||
|
@ -101,27 +130,40 @@ a{text-decoration: none}
|
|||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.el-upload--text .el-icon-upload {
|
||||
font-size: 67px;
|
||||
color: #97a8be;
|
||||
margin: 40px 0 16px;
|
||||
line-height: 50px;
|
||||
}
|
||||
|
||||
.el-upload--text {
|
||||
color: #97a8be;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.el-upload--text em {
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/*VueEditor*/
|
||||
.ql-container{
|
||||
|
||||
.ql-container {
|
||||
min-height: 400px;
|
||||
}
|
||||
.ql-snow .ql-tooltip{
|
||||
|
||||
.ql-snow .ql-tooltip {
|
||||
transform: translateX(117.5px) translateY(10px) !important;
|
||||
}
|
||||
.editor-btn{
|
||||
|
||||
.editor-btn {
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
/*markdown*/
|
||||
|
||||
.v-note-wrapper .v-note-panel {
|
||||
min-height: 500px;
|
||||
}
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
.v-note-wrapper{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.v-note-wrapper .v-note-op{
|
||||
display: flex;
|
||||
flex: none;
|
||||
}
|
||||
.v-note-wrapper .v-note-op .left,
|
||||
.v-note-wrapper .v-note-op .right{
|
||||
flex: 1;
|
||||
}
|
||||
.v-note-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.v-note-wrapper .v-note-op {
|
||||
display: flex;
|
||||
flex: none;
|
||||
}
|
||||
.v-note-wrapper .v-note-op .left,
|
||||
.v-note-wrapper .v-note-op .right {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.v-note-wrapper .v-note-panel {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
min-height: 500px;
|
||||
}
|
||||
.v-note-wrapper .v-note-panel .v-note-edit.divarea-wrapper {
|
||||
flex: 0 0 50%;
|
||||
}
|
||||
|
||||
.v-note-wrapper .v-note-panel .v-note-edit.divarea-wrapper.single-edit {
|
||||
flex: 0 0 100%;
|
||||
}
|
||||
.v-note-wrapper .v-note-panel .v-note-edit.divarea-wrapper.single-show {
|
||||
width: 0;
|
||||
flex: 0 0 0;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.v-note-wrapper .v-note-panel .v-note-show {
|
||||
flex: 0 0 50%;
|
||||
}
|
||||
.v-note-wrapper .v-note-panel .v-note-show.single-show {
|
||||
flex: 0 0 100%;
|
||||
}
|
||||
|
||||
.v-note-wrapper .v-note-panel .v-note-navigation-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.v-note-wrapper .v-note-panel .v-note-navigation-wrapper .v-note-navigation-title {
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.v-note-wrapper .v-note-panel .v-note-navigation-wrapper .v-note-navigation-content {
|
||||
flex: 1;
|
||||
}
|
||||
.v-note-img-wrapper{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.v-note-img-wrapper img {
|
||||
flex: 0 0 auto;
|
||||
}
|
|
@ -1,27 +1,29 @@
|
|||
.header{
|
||||
background-color: #00d1b2;
|
||||
}
|
||||
.login-wrap{
|
||||
background: rgba(56, 157, 170, 0.82);;
|
||||
}
|
||||
.plugins-tips{
|
||||
background: #f2f2f2;
|
||||
}
|
||||
.plugins-tips a{
|
||||
color: #00d1b2;
|
||||
}
|
||||
.el-upload--text em {
|
||||
color: #00d1b2;
|
||||
}
|
||||
.pure-button{
|
||||
background: #00d1b2;
|
||||
}
|
||||
.vue-datasource .btn-primary {
|
||||
color: #fff;
|
||||
background-color: #00d1b2 !important;
|
||||
border-color: #00d1b2 !important;
|
||||
}
|
||||
.pagination > .active > a, .pagination > .active > a:hover, .pagination > .active > a:focus, .pagination > .active > span, .pagination > .active > span:hover, .pagination > .active > span:focus {
|
||||
background-color: #00d1b2 !important;
|
||||
border-color: #00d1b2 !important;
|
||||
.header{
|
||||
background-color: #07c4a8;
|
||||
}
|
||||
.login-wrap{
|
||||
background: rgba(56, 157, 170, 0.82);;
|
||||
}
|
||||
.plugins-tips{
|
||||
background: #f2f2f2;
|
||||
}
|
||||
.plugins-tips a{
|
||||
color: #00d1b2;
|
||||
}
|
||||
.el-upload--text em {
|
||||
color: #00d1b2;
|
||||
}
|
||||
.pure-button{
|
||||
background: #00d1b2;
|
||||
}
|
||||
.pagination > .active > a, .pagination > .active > a:hover, .pagination > .active > a:focus, .pagination > .active > span, .pagination > .active > span:hover, .pagination > .active > span:focus {
|
||||
background-color: #00d1b2 !important;
|
||||
border-color: #00d1b2 !important;
|
||||
}
|
||||
.tags-li.active {
|
||||
border: 1px solid #00d1b2;
|
||||
background-color: #00d1b2;
|
||||
}
|
||||
.collapse-btn:hover{
|
||||
background: #00d1b2;
|
||||
}
|
162
static/data.json
162
static/data.json
|
@ -1,162 +0,0 @@
|
|||
{
|
||||
"pagination": {
|
||||
"total": 15,
|
||||
"per_page": 15,
|
||||
"current_page": 1,
|
||||
"last_page": 1,
|
||||
"from": 1,
|
||||
"to": 15
|
||||
},
|
||||
"data": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Jaylen Schmidt",
|
||||
"email": "aheaney@example.org",
|
||||
"city": "Conroyburgh",
|
||||
"company": "Kunde, Gerhold and Runte",
|
||||
"job": "Soil Scientist",
|
||||
"created_at": "2017-01-13 19:17:16",
|
||||
"updated_at": "2017-01-13 19:17:16"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Ms. Desiree Franecki III",
|
||||
"email": "pweissnat@example.net",
|
||||
"city": "New Mathew",
|
||||
"company": "Davis Ltd",
|
||||
"job": "Customer Service Representative",
|
||||
"created_at": "2017-01-13 19:17:16",
|
||||
"updated_at": "2017-01-13 19:17:16"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Clyde Corwin",
|
||||
"email": "rolfson.lexus@example.com",
|
||||
"city": "East Ron",
|
||||
"company": "Zieme and Sons",
|
||||
"job": "Claims Taker",
|
||||
"created_at": "2017-01-13 19:17:16",
|
||||
"updated_at": "2017-01-13 19:17:16"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "Mr. Tyrese Kuphal",
|
||||
"email": "libby.heaney@example.com",
|
||||
"city": "Cristianland",
|
||||
"company": "Abernathy LLC",
|
||||
"job": "Occupational Health Safety Technician",
|
||||
"created_at": "2017-01-13 19:17:16",
|
||||
"updated_at": "2017-01-13 19:17:16"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "Ms. Amya West PhD",
|
||||
"email": "uheller@example.org",
|
||||
"city": "Treutelmouth",
|
||||
"company": "Mraz-Effertz",
|
||||
"job": "Hazardous Materials Removal Worker",
|
||||
"created_at": "2017-01-13 19:17:16",
|
||||
"updated_at": "2017-01-13 19:17:16"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "Murphy Stamm IV",
|
||||
"email": "ckautzer@example.com",
|
||||
"city": "Myleneshire",
|
||||
"company": "Sporer-Wolf",
|
||||
"job": "Pipelaying Fitter",
|
||||
"created_at": "2017-01-13 19:17:16",
|
||||
"updated_at": "2017-01-13 19:17:16"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "Elsa Jast",
|
||||
"email": "kaitlyn.lang@example.net",
|
||||
"city": "Mariahstad",
|
||||
"company": "Hackett LLC",
|
||||
"job": "Record Clerk",
|
||||
"created_at": "2017-01-13 19:17:16",
|
||||
"updated_at": "2017-01-13 19:17:16"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "Hardy Mosciski DVM",
|
||||
"email": "soledad44@example.net",
|
||||
"city": "Jasminborough",
|
||||
"company": "Haley Ltd",
|
||||
"job": "Kindergarten Teacher",
|
||||
"created_at": "2017-01-13 19:17:16",
|
||||
"updated_at": "2017-01-13 19:17:16"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "Demarcus Littel",
|
||||
"email": "americo84@example.com",
|
||||
"city": "New Lilaton",
|
||||
"company": "Satterfield Group",
|
||||
"job": "Plant Scientist",
|
||||
"created_at": "2017-01-13 19:17:16",
|
||||
"updated_at": "2017-01-13 19:17:16"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "Dr. Shad Gleichner",
|
||||
"email": "eleanora23@example.com",
|
||||
"city": "Lake Whitneyberg",
|
||||
"company": "Fay Group",
|
||||
"job": "Rotary Drill Operator",
|
||||
"created_at": "2017-01-13 19:17:16",
|
||||
"updated_at": "2017-01-13 19:17:16"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "Milford Mann",
|
||||
"email": "shartmann@example.net",
|
||||
"city": "Lake Austinport",
|
||||
"company": "Sporer-Langosh",
|
||||
"job": "Social and Human Service Assistant",
|
||||
"created_at": "2017-01-13 19:17:16",
|
||||
"updated_at": "2017-01-13 19:17:16"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "Prof. Mustafa Lindgren Sr.",
|
||||
"email": "lizeth.morissette@example.net",
|
||||
"city": "Roweborough",
|
||||
"company": "Mitchell-Ratke",
|
||||
"job": "Shoe Machine Operators",
|
||||
"created_at": "2017-01-13 19:17:16",
|
||||
"updated_at": "2017-01-13 19:17:16"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "Mrs. Brittany Bode Sr.",
|
||||
"email": "wiegand.mozelle@example.org",
|
||||
"city": "South Maxwellville",
|
||||
"company": "Reilly Inc",
|
||||
"job": "Bridge Tender OR Lock Tender",
|
||||
"created_at": "2017-01-13 19:17:16",
|
||||
"updated_at": "2017-01-13 19:17:16"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"name": "Dariana Bauch",
|
||||
"email": "dessie.schamberger@example.net",
|
||||
"city": "East Linnie",
|
||||
"company": "Wuckert PLC",
|
||||
"job": "Elementary and Secondary School Administrators",
|
||||
"created_at": "2017-01-13 19:17:16",
|
||||
"updated_at": "2017-01-13 19:17:16"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "Jalon Renner",
|
||||
"email": "lulu45@example.net",
|
||||
"city": "New Rashad",
|
||||
"company": "Muller-Kuhn",
|
||||
"job": "Manufactured Building Installer",
|
||||
"created_at": "2017-01-13 19:17:16",
|
||||
"updated_at": "2017-01-13 19:17:16"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
{
|
||||
"data": [{
|
||||
"id": 1,
|
||||
"name": "段娜",
|
||||
"email": "g.rgiuory@kctbut.mw",
|
||||
"ip": "68.28.4.232"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "蔡洋",
|
||||
"email": "y.mwjjoje@lpkshev.tg",
|
||||
"ip": "22.126.12.189"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "陈敏",
|
||||
"email": "e.voaiiuo@mvng.sn",
|
||||
"ip": "227.89.13.37"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "朱平",
|
||||
"email": "e.lduuf@nkfypn.az",
|
||||
"ip": "9.39.240.243"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "侯平",
|
||||
"email": "t.czqjyndts@jmwenklns.md",
|
||||
"ip": "178.162.29.113"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "常超",
|
||||
"email": "d.dhysgem@uxpcutmlk.tt",
|
||||
"ip": "192.50.103.170"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "许平",
|
||||
"email": "g.fiqdonvbc@wanepptw.tv",
|
||||
"ip": "73.20.99.60"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "毛超",
|
||||
"email": "w.unyyejh@qus.gt",
|
||||
"ip": "10.88.135.123"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "周磊",
|
||||
"email": "e.qbejguqqg@ejpxhltoak.gw",
|
||||
"ip": "244.221.237.210"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "胡秀英",
|
||||
"email": "s.dszo@uxaojtj.sy",
|
||||
"ip": "86.199.17.210"
|
||||
}
|
||||
],
|
||||
"pagination": {
|
||||
"total": 15,
|
||||
"per_page": 15,
|
||||
"current_page": 1,
|
||||
"last_page": 1,
|
||||
"from": 1,
|
||||
"to": 15
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue