commit
9939520b0b
55 changed files with 3803 additions and 0 deletions
@ -0,0 +1,3 @@ |
|||
> 1% |
|||
last 2 versions |
|||
not ie <= 8 |
|||
@ -0,0 +1,12 @@ |
|||
# These are supported funding model platforms |
|||
|
|||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] |
|||
patreon: # Replace with a single Patreon username |
|||
open_collective: # Replace with a single Open Collective username |
|||
ko_fi: # Replace with a single Ko-fi username |
|||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel |
|||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry |
|||
liberapay: # Replace with a single Liberapay username |
|||
issuehunt: # Replace with a single IssueHunt username |
|||
otechie: # Replace with a single Otechie username |
|||
custom: https://lin-xin.gitee.io/images/weixin.jpg |
|||
@ -0,0 +1,22 @@ |
|||
.DS_Store |
|||
node_modules |
|||
/dist |
|||
example.html |
|||
favicon.ico |
|||
# 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* |
|||
@ -0,0 +1,6 @@ |
|||
{ |
|||
"tabWidth": 4, |
|||
"singleQuote": true, |
|||
"trailingComma": "none", |
|||
"printWidth": 140 |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
MIT License |
|||
|
|||
Copyright (c) 2016-2019 vue-manage-system |
|||
|
|||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
of this software and associated documentation files (the "Software"), to deal |
|||
in the Software without restriction, including without limitation the rights |
|||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|||
copies of the Software, and to permit persons to whom the Software is |
|||
furnished to do so, subject to the following conditions: |
|||
|
|||
The above copyright notice and this permission notice shall be included in all |
|||
copies or substantial portions of the Software. |
|||
|
|||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|||
SOFTWARE. |
|||
@ -0,0 +1,197 @@ |
|||
# vue-manage-system |
|||
|
|||
<a href="https://github.com/vuejs/vue"> |
|||
<img src="https://img.shields.io/badge/vue-2.6.10-brightgreen.svg" alt="vue"> |
|||
</a> |
|||
<a href="https://github.com/ElemeFE/element"> |
|||
<img src="https://img.shields.io/badge/element--ui-2.8.2-brightgreen.svg" alt="element-ui"> |
|||
</a> |
|||
<a href="https://github.com/lin-xin/vue-manage-system/blob/master/LICENSE"> |
|||
<img src="https://img.shields.io/github/license/mashape/apistatus.svg" alt="license"> |
|||
</a> |
|||
<a href="https://github.com/lin-xin/vue-manage-system/releases"> |
|||
<img src="https://img.shields.io/github/release/lin-xin/vue-manage-system.svg" alt="GitHub release"> |
|||
</a> |
|||
<a href="https://lin-xin.gitee.io/example/work/#/donate"> |
|||
<img src="https://img.shields.io/badge/%24-donate-ff69b4.svg" alt="donate"> |
|||
</a> |
|||
|
|||
基于 Vue + Element UI 的后台管理系统解决方案。[线上地址](https://lin-xin.gitee.io/example/work/) |
|||
|
|||
> React + Ant Design 的版本正在开发中,仓库地址:[react-manage-system](https://github.com/lin-xin/react-manage-system) |
|||
|
|||
[English document](https://github.com/lin-xin/manage-system/blob/master/README_EN.md) |
|||
|
|||
## 项目截图 |
|||
|
|||
### 登录 |
|||
|
|||
 |
|||
|
|||
### 默认皮肤 |
|||
|
|||
 |
|||
|
|||
### 浅绿色皮肤 |
|||
|
|||
 |
|||
|
|||
## 赞赏 |
|||
|
|||
请作者喝杯咖啡吧!(微信号:linxin_20) |
|||
|
|||
 |
|||
|
|||
## 特别鸣谢 |
|||
|
|||
- [实验楼](https://www.shiyanlou.com?source=vue-manage-system) |
|||
|
|||
## 前言 |
|||
|
|||
该方案作为一套多功能的后台框架模板,适用于绝大部分的后台管理系统(Web Management System)开发。基于 vue.js,使用 vue-cli3 脚手架,引用 Element UI 组件库,方便开发快速简洁好看的组件。分离颜色样式,支持手动切换主题色,而且很方便使用自定义主题色。 |
|||
|
|||
## 功能 |
|||
|
|||
- [x] Element UI |
|||
- [x] 登录/注销 |
|||
- [x] Dashboard |
|||
- [x] 表格 |
|||
- [x] Tab 选项卡 |
|||
- [x] 表单 |
|||
- [x] 图表 :bar_chart: |
|||
- [x] 富文本编辑器 |
|||
- [x] markdown 编辑器 |
|||
- [x] 图片拖拽/裁剪上传 |
|||
- [x] 支持切换主题色 :sparkles: |
|||
- [x] 列表拖拽排序 |
|||
- [x] 权限测试 |
|||
- [x] 404 / 403 |
|||
- [x] 三级菜单 |
|||
- [x] 自定义图标 |
|||
- [x] 可拖拽弹窗 |
|||
- [x] 国际化 |
|||
|
|||
## 安装步骤 |
|||
|
|||
``` |
|||
git clone https://github.com/lin-xin/vue-manage-system.git // 把模板下载到本地 |
|||
cd vue-manage-system // 进入模板目录 |
|||
npm install // 安装项目依赖,等待安装完成之后,安装失败可用 cnpm 或 yarn |
|||
|
|||
// 开启服务器,浏览器访问 http://localhost:8080 |
|||
npm run serve |
|||
|
|||
// 执行构建命令,生成的dist文件夹放在服务器下即可访问 |
|||
npm run build |
|||
``` |
|||
|
|||
## 组件使用说明与演示 |
|||
|
|||
### vue-schart |
|||
|
|||
vue.js 封装 sChart.js 的图表组件。访问地址:[vue-schart](https://github.com/linxin/vue-schart) |
|||
|
|||
<p><a href="https://www.npmjs.com/package/vue-schart"><img src="https://img.shields.io/npm/dm/vue-schart.svg" alt="Downloads"></a></p> |
|||
|
|||
```html |
|||
<template> |
|||
<div> |
|||
<schart class="wrapper" canvasId="myCanvas" :options="options"></schart> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import Schart from 'vue-schart'; // 导入Schart组件 |
|||
export default { |
|||
data() { |
|||
return { |
|||
options: { |
|||
type: 'bar', |
|||
title: { |
|||
text: '最近一周各品类销售图' |
|||
}, |
|||
labels: ['周一', '周二', '周三', '周四', '周五'], |
|||
datasets: [ |
|||
{ |
|||
label: '家电', |
|||
data: [234, 278, 270, 190, 230] |
|||
}, |
|||
{ |
|||
label: '百货', |
|||
data: [164, 178, 190, 135, 160] |
|||
}, |
|||
{ |
|||
label: '食品', |
|||
data: [144, 198, 150, 235, 120] |
|||
} |
|||
] |
|||
} |
|||
}; |
|||
}, |
|||
components: { |
|||
Schart |
|||
} |
|||
}; |
|||
</script> |
|||
<style> |
|||
.wrapper { |
|||
width: 7rem; |
|||
height: 5rem; |
|||
} |
|||
</style> |
|||
``` |
|||
|
|||
## 其他注意事项 |
|||
|
|||
### 一、如果我不想用到上面的某些组件呢,那我怎么在模板中删除掉不影响到其他功能呢? |
|||
|
|||
举个栗子,我不想用 Vue-Quill-Editor 这个组件,那我需要分四步走。 |
|||
|
|||
第一步:删除该组件的路由,在目录 src/router/index.js 中,找到引入改组件的路由,删除下面这段代码。 |
|||
|
|||
```JavaScript |
|||
{ |
|||
// 富文本编辑器组件 |
|||
path: '/editor', |
|||
component: resolve => require(['../components/page/VueEditor.vue'], resolve) |
|||
}, |
|||
``` |
|||
|
|||
第二步:删除引入该组件的文件。在目录 src/components/page/ 删除 VueEditor.vue 文件。 |
|||
|
|||
第三步:删除该页面的入口。在目录 src/components/common/Sidebar.vue 中,找到该入口,删除下面这段代码。 |
|||
|
|||
```js |
|||
{ |
|||
index: 'editor', |
|||
title: '富文本编辑器' |
|||
}, |
|||
``` |
|||
|
|||
第四步:卸载该组件。执行以下命令: |
|||
npm un vue-quill-editor -S |
|||
|
|||
完成。 |
|||
|
|||
### 二、如何切换主题色呢? |
|||
|
|||
第一步:打开 src/main.js 文件,找到引入 element 样式的地方,换成浅绿色主题。 |
|||
|
|||
```javascript |
|||
import 'element-ui/lib/theme-default/index.css'; // 默认主题 |
|||
// import './assets/css/theme-green/index.css'; // 浅绿色主题 |
|||
``` |
|||
|
|||
第二步:打开 src/App.vue 文件,找到 style 标签引入样式的地方,切换成浅绿色主题。 |
|||
|
|||
```javascript |
|||
@import "./assets/css/main.css"; |
|||
@import "./assets/css/color-dark.css"; /*深色主题*/ |
|||
/*@import "./assets/css/theme-green/color-green.css"; !*浅绿色主题*!*/ |
|||
``` |
|||
|
|||
第三步:打开 src/components/common/Sidebar.vue 文件,找到 el-menu 标签,把 background-color/text-color/active-text-color 属性去掉即可。 |
|||
|
|||
## License |
|||
|
|||
[MIT](https://github.com/lin-xin/vue-manage-system/blob/master/LICENSE) |
|||
@ -0,0 +1,196 @@ |
|||
# vue-manage-system |
|||
|
|||
<a href="https://github.com/vuejs/vue"> |
|||
<img src="https://img.shields.io/badge/vue-2.6.10-brightgreen.svg" alt="vue"> |
|||
</a> |
|||
<a href="https://github.com/ElemeFE/element"> |
|||
<img src="https://img.shields.io/badge/element--ui-2.8.2-brightgreen.svg" alt="element-ui"> |
|||
</a> |
|||
<a href="https://github.com/lin-xin/vue-manage-system/blob/master/LICENSE"> |
|||
<img src="https://img.shields.io/github/license/mashape/apistatus.svg" alt="license"> |
|||
</a> |
|||
<a href="https://github.com/lin-xin/vue-manage-system/releases"> |
|||
<img src="https://img.shields.io/github/release/lin-xin/vue-manage-system.svg" alt="GitHub release"> |
|||
</a> |
|||
<a href="https://lin-xin.gitee.io/example/work/#/donate"> |
|||
<img src="https://img.shields.io/badge/%24-donate-ff69b4.svg" alt="donate"> |
|||
</a> |
|||
|
|||
The web management system solution based on Vue2 and Element-UI。[live demo](https://lin-xin.gitee.io/example/work/) |
|||
|
|||
## Donation |
|||
|
|||
 |
|||
|
|||
## Preface |
|||
|
|||
The scheme as a set of multi-function background frame templates, suitable for most of the WEB management system development. Convenient development fast simple good components based on Vue2 and Element-UI. Color separation of color style, support manual switch themes, and it is convenient to use a custom theme color. |
|||
|
|||
## Function |
|||
|
|||
- [x] Element-UI |
|||
- [x] Login/Logout |
|||
- [x] Dashboard |
|||
- [x] Table |
|||
- [x] Tabs |
|||
- [x] From |
|||
- [x] Chart :bar_chart: |
|||
- [x] Editor |
|||
- [x] Markdown |
|||
- [x] Upload pictures by clipping or dragging |
|||
- [x] Support manual switch themes :sparkles: |
|||
- [x] List drag sort |
|||
- [x] Permission |
|||
- [x] 404 / 403 |
|||
- [x] Three level menu |
|||
- [x] Custom icon |
|||
|
|||
## Installation steps |
|||
|
|||
git clone https://github.com/lin-xin/vue-manage-system.git // Clone templates |
|||
cd vue-manage-system // Enter template directory |
|||
npm install // Installation dependency |
|||
|
|||
## Local development |
|||
|
|||
// Open server and access http://localhost:8080 in browser |
|||
npm run serve |
|||
|
|||
## Constructing production |
|||
|
|||
// Constructing project |
|||
npm run build |
|||
|
|||
## Component description and presentation |
|||
|
|||
### vue-schart |
|||
|
|||
Vue.js wrapper for sChart.js. Github : [vue-schart](https://github.com/linxin/vue-schart) |
|||
|
|||
```html |
|||
<template> |
|||
<div> |
|||
<schart class="wrapper" canvasId="myCanvas" :options="options"></schart> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import Schart from 'vue-schart'; // 导入Schart组件 |
|||
export default { |
|||
data() { |
|||
return { |
|||
options: { |
|||
type: 'bar', |
|||
title: { |
|||
text: '最近一周各品类销售图' |
|||
}, |
|||
labels: ['周一', '周二', '周三', '周四', '周五'], |
|||
datasets: [ |
|||
{ |
|||
label: '家电', |
|||
data: [234, 278, 270, 190, 230] |
|||
}, |
|||
{ |
|||
label: '百货', |
|||
data: [164, 178, 190, 135, 160] |
|||
}, |
|||
{ |
|||
label: '食品', |
|||
data: [144, 198, 150, 235, 120] |
|||
} |
|||
] |
|||
} |
|||
}; |
|||
}, |
|||
components: { |
|||
Schart |
|||
} |
|||
}; |
|||
</script> |
|||
<style> |
|||
.wrapper { |
|||
width: 7rem; |
|||
height: 5rem; |
|||
} |
|||
</style> |
|||
``` |
|||
|
|||
### element-ui |
|||
|
|||
A desktop component library based on vue.js2.0 . Github : [element](http://element.eleme.io/#/zh-CN/component/layout) |
|||
|
|||
### Vue-Quill-Editor |
|||
|
|||
Quill editor component for Vue2. Github : [vue-quill-editor](https://github.com/surmon-china/vue-quill-editor) |
|||
|
|||
### mavonEditor |
|||
|
|||
A markdown editor based on Vue that supports a variety of personalized features. Github: [mavonEditor](https://github.com/hinesboy/mavonEditor) |
|||
|
|||
### vue-cropperjs |
|||
|
|||
A Vue wrapper component for cropperjs. Github: [vue-cropperjs](https://github.com/Agontuk/vue-cropperjs) |
|||
|
|||
## 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-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: '/editor', |
|||
component: resolve => require(['../components/page/VueEditor.vue'], resolve) |
|||
}, |
|||
``` |
|||
|
|||
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. |
|||
|
|||
```js |
|||
{ |
|||
index: 'editor', |
|||
title: '富文本编辑器' |
|||
}, |
|||
``` |
|||
|
|||
Finally, uninstall this component. |
|||
npm un vue-quill-editor -S |
|||
|
|||
Complete! |
|||
|
|||
### 二、How to switch themes? |
|||
|
|||
The first step to enter 'src/main.js' and change into green theme. |
|||
|
|||
```javascript |
|||
import 'element-ui/lib/theme-default/index.css'; // default theme |
|||
// import '../static/css/theme-green/index.css'; // green theme |
|||
``` |
|||
|
|||
The second step to enter 'src/App.vue' and change into green theme. |
|||
|
|||
```javascript |
|||
@import "../static/css/main.css"; |
|||
@import "../static/css/color-dark.css"; /*深色主题*/ |
|||
/*@import "../static/css/theme-green/color-green.css"; !*浅绿色主题*!*/ |
|||
``` |
|||
|
|||
Finally,enter 'src/components/common/Sidebar.vue' and find el-menu Tags,delete 'background-color/text-color/active-text-color'。 |
|||
|
|||
## Screenshot |
|||
|
|||
### Default theme |
|||
|
|||
 |
|||
|
|||
### Green theme |
|||
|
|||
 |
|||
|
|||
## License |
|||
|
|||
[MIT](https://github.com/lin-xin/vue-manage-system/blob/master/LICENSE) |
|||
@ -0,0 +1,5 @@ |
|||
module.exports = { |
|||
presets: [ |
|||
'@vue/app' |
|||
] |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
{ |
|||
"name": "vue-manage-system", |
|||
"version": "4.2.0", |
|||
"private": true, |
|||
"scripts": { |
|||
"dev": "npm run serve", |
|||
"serve": "vue-cli-service serve", |
|||
"build": "vue-cli-service build" |
|||
}, |
|||
"dependencies": { |
|||
"axios": "^0.18.0", |
|||
"babel-polyfill": "^6.26.0", |
|||
"element-ui": "^2.11.0", |
|||
"mavon-editor": "^2.6.17", |
|||
"vue": "^2.6.10", |
|||
"vue-cropperjs": "^3.0.0", |
|||
"vue-i18n": "^8.10.0", |
|||
"vue-quill-editor": "^3.0.6", |
|||
"vue-router": "^3.0.3", |
|||
"vue-schart": "^2.0.0", |
|||
"vuedraggable": "^2.17.0" |
|||
}, |
|||
"devDependencies": { |
|||
"@vue/cli-plugin-babel": "^3.9.0", |
|||
"@vue/cli-service": "^3.9.0", |
|||
"vue-template-compiler": "^2.6.10" |
|||
} |
|||
} |
|||
@ -0,0 +1,5 @@ |
|||
module.exports = { |
|||
plugins: { |
|||
autoprefixer: {} |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
<!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,minimum-scale=1,maximum-scale=1,user-scalable=no"> |
|||
<link rel="stylesheet" href="//at.alicdn.com/t/font_830376_qzecyukz0s.css"> |
|||
<title>vue-manage-system</title> |
|||
</head> |
|||
<body> |
|||
<noscript> |
|||
<strong>We're sorry but vms 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> |
|||
@ -0,0 +1,40 @@ |
|||
{ |
|||
"list": [{ |
|||
"id": 1, |
|||
"name": "张三", |
|||
"money": 123, |
|||
"address": "广东省东莞市长安镇", |
|||
"state": "成功", |
|||
"date": "2019-11-1", |
|||
"thumb": "https://lin-xin.gitee.io/images/post/wms.png" |
|||
}, |
|||
{ |
|||
"id": 2, |
|||
"name": "李四", |
|||
"money": 456, |
|||
"address": "广东省广州市白云区", |
|||
"state": "成功", |
|||
"date": "2019-10-11", |
|||
"thumb": "https://lin-xin.gitee.io/images/post/node3.png" |
|||
}, |
|||
{ |
|||
"id": 3, |
|||
"name": "王五", |
|||
"money": 789, |
|||
"address": "湖南省长沙市", |
|||
"state": "失败", |
|||
"date": "2019-11-11", |
|||
"thumb": "https://lin-xin.gitee.io/images/post/parcel.png" |
|||
}, |
|||
{ |
|||
"id": 4, |
|||
"name": "赵六", |
|||
"money": 1011, |
|||
"address": "福建省厦门市鼓浪屿", |
|||
"state": "成功", |
|||
"date": "2019-10-20", |
|||
"thumb": "https://lin-xin.gitee.io/images/post/notice.png" |
|||
} |
|||
], |
|||
"pageTotal": 4 |
|||
} |
|||
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 81 KiB |
|
After Width: | Height: | Size: 112 KiB |
@ -0,0 +1,10 @@ |
|||
<template> |
|||
<div id="app"> |
|||
<router-view></router-view> |
|||
</div> |
|||
</template> |
|||
<style> |
|||
@import "./assets/css/main.css"; |
|||
@import "./assets/css/color-dark.css"; /*深色主题*/ |
|||
/*@import "./assets/css/theme-green/color-green.css"; 浅绿色主题*/ |
|||
</style> |
|||
@ -0,0 +1,9 @@ |
|||
import request from '../utils/request'; |
|||
|
|||
export const fetchData = query => { |
|||
return request({ |
|||
url: './table.json', |
|||
method: 'get', |
|||
params: query |
|||
}); |
|||
}; |
|||
@ -0,0 +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; |
|||
} |
|||
.tags-li.active { |
|||
border: 1px solid #409EFF; |
|||
background-color: #409EFF; |
|||
} |
|||
.message-title{ |
|||
color: #20a0ff; |
|||
} |
|||
.collapse-btn:hover{ |
|||
background: rgb(40,52,70); |
|||
} |
|||
@ -0,0 +1,4 @@ |
|||
|
|||
[class*=" el-icon-lx"], [class^=el-icon-lx] { |
|||
font-family: lx-iconfont!important; |
|||
} |
|||
@ -0,0 +1,177 @@ |
|||
* { |
|||
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; |
|||
} |
|||
|
|||
a { |
|||
text-decoration: none |
|||
} |
|||
|
|||
|
|||
.content-box { |
|||
position: absolute; |
|||
left: 250px; |
|||
right: 0; |
|||
top: 70px; |
|||
bottom: 0; |
|||
padding-bottom: 30px; |
|||
-webkit-transition: left .3s ease-in-out; |
|||
transition: left .3s ease-in-out; |
|||
background: #f0f0f0; |
|||
} |
|||
|
|||
.content { |
|||
width: auto; |
|||
height: 100%; |
|||
padding: 10px; |
|||
overflow-y: scroll; |
|||
box-sizing: border-box; |
|||
} |
|||
|
|||
.content-collapse { |
|||
left: 65px; |
|||
} |
|||
|
|||
.container { |
|||
padding: 30px; |
|||
background: #fff; |
|||
border: 1px solid #ddd; |
|||
border-radius: 5px; |
|||
} |
|||
|
|||
.crumbs { |
|||
margin: 10px 0; |
|||
} |
|||
|
|||
.el-table th { |
|||
background-color: #f5f7fa !important; |
|||
} |
|||
|
|||
.pagination { |
|||
margin: 20px 0; |
|||
text-align: right; |
|||
} |
|||
|
|||
.plugins-tips { |
|||
padding: 20px 10px; |
|||
margin-bottom: 20px; |
|||
} |
|||
|
|||
.el-button+.el-tooltip { |
|||
margin-left: 10px; |
|||
} |
|||
|
|||
.el-table tr:hover { |
|||
background: #f6faff; |
|||
} |
|||
|
|||
.mgb20 { |
|||
margin-bottom: 20px; |
|||
} |
|||
|
|||
.move-enter-active, |
|||
.move-leave-active { |
|||
transition: opacity .5s; |
|||
} |
|||
|
|||
.move-enter, |
|||
.move-leave { |
|||
opacity: 0; |
|||
} |
|||
|
|||
/*BaseForm*/ |
|||
|
|||
.form-box { |
|||
width: 600px; |
|||
} |
|||
|
|||
.form-box .line { |
|||
text-align: center; |
|||
} |
|||
|
|||
.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) { |
|||
padding-bottom: 0; |
|||
} |
|||
|
|||
/*Upload*/ |
|||
|
|||
.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; |
|||
} |
|||
|
|||
.el-upload--text { |
|||
background-color: #fff; |
|||
border: 1px dashed #d9d9d9; |
|||
border-radius: 6px; |
|||
box-sizing: border-box; |
|||
width: 360px; |
|||
height: 180px; |
|||
text-align: center; |
|||
cursor: pointer; |
|||
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 { |
|||
min-height: 400px; |
|||
} |
|||
|
|||
.ql-snow .ql-tooltip { |
|||
transform: translateX(117.5px) translateY(10px) !important; |
|||
} |
|||
|
|||
.editor-btn { |
|||
margin-top: 20px; |
|||
} |
|||
|
|||
/*markdown*/ |
|||
|
|||
.v-note-wrapper .v-note-panel { |
|||
min-height: 500px; |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
.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; |
|||
} |
|||
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
@ -0,0 +1,191 @@ |
|||
<template> |
|||
<div class="header"> |
|||
<!-- 折叠按钮 --> |
|||
<div class="collapse-btn" @click="collapseChage"> |
|||
<i v-if="!collapse" class="el-icon-s-fold"></i> |
|||
<i v-else class="el-icon-s-unfold"></i> |
|||
</div> |
|||
<div class="logo">后台管理系统</div> |
|||
<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="../../assets/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="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> |
|||
<script> |
|||
import bus from '../common/bus'; |
|||
export default { |
|||
data() { |
|||
return { |
|||
collapse: false, |
|||
fullscreen: false, |
|||
name: 'linxin', |
|||
message: 2 |
|||
}; |
|||
}, |
|||
computed: { |
|||
username() { |
|||
let username = localStorage.getItem('ms_username'); |
|||
return username ? username : this.name; |
|||
} |
|||
}, |
|||
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; |
|||
} |
|||
}, |
|||
mounted() { |
|||
if (document.body.clientWidth < 1500) { |
|||
this.collapseChage(); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
<style scoped> |
|||
.header { |
|||
position: relative; |
|||
box-sizing: border-box; |
|||
width: 100%; |
|||
height: 70px; |
|||
font-size: 22px; |
|||
color: #fff; |
|||
} |
|||
.collapse-btn { |
|||
float: left; |
|||
padding: 0 21px; |
|||
cursor: pointer; |
|||
line-height: 70px; |
|||
} |
|||
.header .logo { |
|||
float: left; |
|||
width: 250px; |
|||
line-height: 70px; |
|||
} |
|||
.header-right { |
|||
float: right; |
|||
padding-right: 50px; |
|||
} |
|||
.header-user-con { |
|||
display: flex; |
|||
height: 70px; |
|||
align-items: center; |
|||
} |
|||
.btn-fullscreen { |
|||
transform: rotate(45deg); |
|||
margin-right: 5px; |
|||
font-size: 24px; |
|||
} |
|||
.btn-bell, |
|||
.btn-fullscreen { |
|||
position: relative; |
|||
width: 30px; |
|||
height: 30px; |
|||
text-align: center; |
|||
border-radius: 15px; |
|||
cursor: pointer; |
|||
} |
|||
.btn-bell-badge { |
|||
position: absolute; |
|||
right: 0; |
|||
top: -2px; |
|||
width: 8px; |
|||
height: 8px; |
|||
border-radius: 4px; |
|||
background: #f56c6c; |
|||
color: #fff; |
|||
} |
|||
.btn-bell .el-icon-bell { |
|||
color: #fff; |
|||
} |
|||
.user-name { |
|||
margin-left: 10px; |
|||
} |
|||
.user-avator { |
|||
margin-left: 20px; |
|||
} |
|||
.user-avator img { |
|||
display: block; |
|||
width: 40px; |
|||
height: 40px; |
|||
border-radius: 50%; |
|||
} |
|||
.el-dropdown-link { |
|||
color: #fff; |
|||
cursor: pointer; |
|||
} |
|||
.el-dropdown-menu__item { |
|||
text-align: center; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,51 @@ |
|||
<template> |
|||
<div class="wrapper"> |
|||
<v-head></v-head> |
|||
<v-sidebar></v-sidebar> |
|||
<div class="content-box" :class="{'content-collapse':collapse}"> |
|||
<v-tags></v-tags> |
|||
<div class="content"> |
|||
<transition name="move" mode="out-in"> |
|||
<keep-alive :include="tagsList"> |
|||
<router-view></router-view> |
|||
</keep-alive> |
|||
</transition> |
|||
<el-backtop target=".content"></el-backtop> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import vHead from './Header.vue'; |
|||
import vSidebar from './Sidebar.vue'; |
|||
import vTags from './Tags.vue'; |
|||
import bus from './bus'; |
|||
export default { |
|||
data() { |
|||
return { |
|||
tagsList: [], |
|||
collapse: false |
|||
}; |
|||
}, |
|||
components: { |
|||
vHead, |
|||
vSidebar, |
|||
vTags |
|||
}, |
|||
created() { |
|||
bus.$on('collapse-content', msg => { |
|||
this.collapse = msg; |
|||
}); |
|||
|
|||
// 只有在标签页列表里的页面才使用keep-alive,即关闭标签之后就不保存到内存中了。 |
|||
bus.$on('tags', msg => { |
|||
let arr = []; |
|||
for (let i = 0, len = msg.length; i < len; i++) { |
|||
msg[i].name && arr.push(msg[i].name); |
|||
} |
|||
this.tagsList = arr; |
|||
}); |
|||
} |
|||
}; |
|||
</script> |
|||
@ -0,0 +1,189 @@ |
|||
<template> |
|||
<div class="sidebar"> |
|||
<el-menu |
|||
class="sidebar-el-menu" |
|||
:default-active="onRoutes" |
|||
:collapse="collapse" |
|||
background-color="#324157" |
|||
text-color="#bfcbd9" |
|||
active-text-color="#20a0ff" |
|||
unique-opened |
|||
router |
|||
> |
|||
<template v-for="item in items"> |
|||
<template v-if="item.subs"> |
|||
<el-submenu :index="item.index" :key="item.index"> |
|||
<template slot="title"> |
|||
<i :class="item.icon"></i> |
|||
<span slot="title">{{ item.title }}</span> |
|||
</template> |
|||
<template v-for="subItem in item.subs"> |
|||
<el-submenu |
|||
v-if="subItem.subs" |
|||
:index="subItem.index" |
|||
:key="subItem.index" |
|||
> |
|||
<template slot="title">{{ subItem.title }}</template> |
|||
<el-menu-item |
|||
v-for="(threeItem,i) in subItem.subs" |
|||
:key="i" |
|||
:index="threeItem.index" |
|||
>{{ threeItem.title }}</el-menu-item> |
|||
</el-submenu> |
|||
<el-menu-item |
|||
v-else |
|||
:index="subItem.index" |
|||
:key="subItem.index" |
|||
>{{ subItem.title }}</el-menu-item> |
|||
</template> |
|||
</el-submenu> |
|||
</template> |
|||
<template v-else> |
|||
<el-menu-item :index="item.index" :key="item.index"> |
|||
<i :class="item.icon"></i> |
|||
<span slot="title">{{ item.title }}</span> |
|||
</el-menu-item> |
|||
</template> |
|||
</template> |
|||
</el-menu> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import bus from '../common/bus'; |
|||
export default { |
|||
data() { |
|||
return { |
|||
collapse: false, |
|||
items: [ |
|||
{ |
|||
icon: 'el-icon-lx-home', |
|||
index: 'dashboard', |
|||
title: '系统首页' |
|||
}, |
|||
{ |
|||
icon: 'el-icon-lx-cascades', |
|||
index: 'table', |
|||
title: '基础表格' |
|||
}, |
|||
{ |
|||
icon: 'el-icon-lx-copy', |
|||
index: 'tabs', |
|||
title: 'tab选项卡' |
|||
}, |
|||
{ |
|||
icon: 'el-icon-lx-calendar', |
|||
index: '3', |
|||
title: '表单相关', |
|||
subs: [ |
|||
{ |
|||
index: 'form', |
|||
title: '基本表单' |
|||
}, |
|||
{ |
|||
index: '3-2', |
|||
title: '三级菜单', |
|||
subs: [ |
|||
{ |
|||
index: 'editor', |
|||
title: '富文本编辑器' |
|||
}, |
|||
{ |
|||
index: 'markdown', |
|||
title: 'markdown编辑器' |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
index: 'upload', |
|||
title: '文件上传' |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
icon: 'el-icon-lx-emoji', |
|||
index: 'icon', |
|||
title: '自定义图标' |
|||
}, |
|||
{ |
|||
icon: 'el-icon-pie-chart', |
|||
index: 'charts', |
|||
title: 'schart图表' |
|||
}, |
|||
{ |
|||
icon: 'el-icon-rank', |
|||
index: '6', |
|||
title: '拖拽组件', |
|||
subs: [ |
|||
{ |
|||
index: 'drag', |
|||
title: '拖拽列表' |
|||
}, |
|||
{ |
|||
index: 'dialog', |
|||
title: '拖拽弹框' |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
icon: 'el-icon-lx-global', |
|||
index: 'i18n', |
|||
title: '国际化功能' |
|||
}, |
|||
{ |
|||
icon: 'el-icon-lx-warn', |
|||
index: '7', |
|||
title: '错误处理', |
|||
subs: [ |
|||
{ |
|||
index: 'permission', |
|||
title: '权限测试' |
|||
}, |
|||
{ |
|||
index: '404', |
|||
title: '404页面' |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
icon: 'el-icon-lx-redpacket_fill', |
|||
index: '/donate', |
|||
title: '支持作者' |
|||
} |
|||
] |
|||
}; |
|||
}, |
|||
computed: { |
|||
onRoutes() { |
|||
return this.$route.path.replace('/', ''); |
|||
} |
|||
}, |
|||
created() { |
|||
// 通过 Event Bus 进行组件间通信,来折叠侧边栏 |
|||
bus.$on('collapse', msg => { |
|||
this.collapse = msg; |
|||
bus.$emit('collapse-content', msg); |
|||
}); |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.sidebar { |
|||
display: block; |
|||
position: absolute; |
|||
left: 0; |
|||
top: 70px; |
|||
bottom: 0; |
|||
overflow-y: scroll; |
|||
} |
|||
.sidebar::-webkit-scrollbar { |
|||
width: 0; |
|||
} |
|||
.sidebar-el-menu:not(.el-menu--collapse) { |
|||
width: 250px; |
|||
} |
|||
.sidebar > ul { |
|||
height: 100%; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,186 @@ |
|||
<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> |
|||
import bus from './bus'; |
|||
export default { |
|||
data() { |
|||
return { |
|||
tagsList: [] |
|||
} |
|||
}, |
|||
methods: { |
|||
isActive(path) { |
|||
return path === this.$route.fullPath; |
|||
}, |
|||
// 关闭单个标签 |
|||
closeTags(index) { |
|||
const delItem = this.tagsList.splice(index, 1)[0]; |
|||
const item = this.tagsList[index] ? this.tagsList[index] : this.tagsList[index - 1]; |
|||
if (item) { |
|||
delItem.path === this.$route.fullPath && this.$router.push(item.path); |
|||
}else{ |
|||
this.$router.push('/'); |
|||
} |
|||
}, |
|||
// 关闭全部标签 |
|||
closeAll(){ |
|||
this.tagsList = []; |
|||
this.$router.push('/'); |
|||
}, |
|||
// 关闭其他标签 |
|||
closeOther(){ |
|||
const curItem = this.tagsList.filter(item => { |
|||
return item.path === this.$route.fullPath; |
|||
}) |
|||
this.tagsList = curItem; |
|||
}, |
|||
// 设置标签 |
|||
setTags(route){ |
|||
const isExist = this.tagsList.some(item => { |
|||
return item.path === route.fullPath; |
|||
}) |
|||
if(!isExist){ |
|||
if(this.tagsList.length >= 8){ |
|||
this.tagsList.shift(); |
|||
} |
|||
this.tagsList.push({ |
|||
title: route.meta.title, |
|||
path: route.fullPath, |
|||
name: route.matched[1].components.default.name |
|||
}) |
|||
} |
|||
bus.$emit('tags', this.tagsList); |
|||
}, |
|||
handleTags(command){ |
|||
command === 'other' ? this.closeOther() : this.closeAll(); |
|||
} |
|||
}, |
|||
computed: { |
|||
showTags() { |
|||
return this.tagsList.length > 0; |
|||
} |
|||
}, |
|||
watch:{ |
|||
$route(newValue, oldValue){ |
|||
this.setTags(newValue); |
|||
} |
|||
}, |
|||
created(){ |
|||
this.setTags(this.$route); |
|||
// 监听关闭当前页面的标签页 |
|||
bus.$on('close_current_tags', () => { |
|||
for (let i = 0, len = this.tagsList.length; i < len; i++) { |
|||
const item = this.tagsList[i]; |
|||
if(item.path === this.$route.fullPath){ |
|||
if(i < len - 1){ |
|||
this.$router.push(this.tagsList[i+1].path); |
|||
}else if(i > 0){ |
|||
this.$router.push(this.tagsList[i-1].path); |
|||
}else{ |
|||
this.$router.push('/'); |
|||
} |
|||
this.tagsList.splice(i, 1); |
|||
break; |
|||
} |
|||
} |
|||
}) |
|||
} |
|||
} |
|||
|
|||
</script> |
|||
|
|||
|
|||
<style> |
|||
.tags { |
|||
position: relative; |
|||
height: 30px; |
|||
overflow: hidden; |
|||
background: #fff; |
|||
padding-right: 120px; |
|||
box-shadow: 0 5px 10px #ddd; |
|||
} |
|||
|
|||
.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,6 @@ |
|||
import Vue from 'vue'; |
|||
|
|||
// 使用 Event Bus
|
|||
const bus = new Vue(); |
|||
|
|||
export default bus; |
|||
@ -0,0 +1,80 @@ |
|||
import Vue from 'vue'; |
|||
|
|||
// v-dialogDrag: 弹窗拖拽属性
|
|||
Vue.directive('dialogDrag', { |
|||
bind(el, binding, vnode, oldVnode) { |
|||
const dialogHeaderEl = el.querySelector('.el-dialog__header'); |
|||
const dragDom = el.querySelector('.el-dialog'); |
|||
|
|||
dialogHeaderEl.style.cssText += ';cursor:move;' |
|||
dragDom.style.cssText += ';top:0px;' |
|||
|
|||
// 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
|
|||
const sty = (() => { |
|||
if (window.document.currentStyle) { |
|||
return (dom, attr) => dom.currentStyle[attr]; |
|||
} else { |
|||
return (dom, attr) => getComputedStyle(dom, false)[attr]; |
|||
} |
|||
})() |
|||
|
|||
dialogHeaderEl.onmousedown = (e) => { |
|||
// 鼠标按下,计算当前元素距离可视区的距离
|
|||
const disX = e.clientX - dialogHeaderEl.offsetLeft; |
|||
const disY = e.clientY - dialogHeaderEl.offsetTop; |
|||
|
|||
const screenWidth = document.body.clientWidth; // body当前宽度
|
|||
const screenHeight = document.documentElement.clientHeight; // 可见区域高度(应为body高度,可某些环境下无法获取)
|
|||
|
|||
const dragDomWidth = dragDom.offsetWidth; // 对话框宽度
|
|||
const dragDomheight = dragDom.offsetHeight; // 对话框高度
|
|||
|
|||
const minDragDomLeft = dragDom.offsetLeft; |
|||
const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth; |
|||
|
|||
const minDragDomTop = dragDom.offsetTop; |
|||
const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomheight; |
|||
|
|||
|
|||
// 获取到的值带px 正则匹配替换
|
|||
let styL = sty(dragDom, 'left'); |
|||
let styT = sty(dragDom, 'top'); |
|||
|
|||
// 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
|
|||
if (styL.includes('%')) { |
|||
styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100); |
|||
styT = +document.body.clientHeight * (+styT.replace(/\%/g, '') / 100); |
|||
} else { |
|||
styL = +styL.replace(/\px/g, ''); |
|||
styT = +styT.replace(/\px/g, ''); |
|||
}; |
|||
|
|||
document.onmousemove = function (e) { |
|||
// 通过事件委托,计算移动的距离
|
|||
let left = e.clientX - disX; |
|||
let top = e.clientY - disY; |
|||
|
|||
// 边界处理
|
|||
if (-(left) > minDragDomLeft) { |
|||
left = -(minDragDomLeft); |
|||
} else if (left > maxDragDomLeft) { |
|||
left = maxDragDomLeft; |
|||
} |
|||
|
|||
if (-(top) > minDragDomTop) { |
|||
top = -(minDragDomTop); |
|||
} else if (top > maxDragDomTop) { |
|||
top = maxDragDomTop; |
|||
} |
|||
|
|||
// 移动当前元素
|
|||
dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;`; |
|||
}; |
|||
|
|||
document.onmouseup = function (e) { |
|||
document.onmousemove = null; |
|||
document.onmouseup = null; |
|||
}; |
|||
} |
|||
} |
|||
}) |
|||
@ -0,0 +1,30 @@ |
|||
export const messages = { |
|||
'zh': { |
|||
i18n: { |
|||
breadcrumb: '国际化产品', |
|||
tips: '通过切换语言按钮,来改变当前内容的语言。', |
|||
btn: '切换英文', |
|||
title1: '常用用法', |
|||
p1: '要是你把你的秘密告诉了风,那就别怪风把它带给树。', |
|||
p2: '没有什么比信念更能支撑我们度过艰难的时光了。', |
|||
p3: '只要能把自己的事做好,并让自己快乐,你就领先于大多数人了。', |
|||
title2: '组件插值', |
|||
info: 'Element组件需要国际化,请参考 {action}。', |
|||
value: '文档' |
|||
} |
|||
}, |
|||
'en': { |
|||
i18n: { |
|||
breadcrumb: 'International Products', |
|||
tips: 'Click on the button to change the current language. ', |
|||
btn: 'Switch Chinese', |
|||
title1: 'Common usage', |
|||
p1: "If you reveal your secrets to the wind you should not blame the wind for revealing them to the trees.", |
|||
p2: "Nothing can help us endure dark times better than our faith. ", |
|||
p3: "If you can do what you do best and be happy, you're further along in life than most people.", |
|||
title2: 'Component interpolation', |
|||
info: 'The default language of Element is Chinese. If you wish to use another language, please refer to the {action}.', |
|||
value: 'documentation' |
|||
} |
|||
} |
|||
} |
|||
@ -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> |
|||
@ -0,0 +1,149 @@ |
|||
<template> |
|||
<div> |
|||
<div class="crumbs"> |
|||
<el-breadcrumb separator="/"> |
|||
<el-breadcrumb-item> |
|||
<i class="el-icon-pie-chart"></i> schart图表 |
|||
</el-breadcrumb-item> |
|||
</el-breadcrumb> |
|||
</div> |
|||
<div class="container"> |
|||
<div class="plugins-tips"> |
|||
vue-schart:vue.js封装sChart.js的图表组件。 |
|||
访问地址: |
|||
<a |
|||
href="https://github.com/lin-xin/vue-schart" |
|||
target="_blank" |
|||
>vue-schart</a> |
|||
</div> |
|||
<div class="schart-box"> |
|||
<div class="content-title">柱状图</div> |
|||
<schart class="schart" canvasId="bar" :options="options1"></schart> |
|||
</div> |
|||
<div class="schart-box"> |
|||
<div class="content-title">折线图</div> |
|||
<schart class="schart" canvasId="line" :options="options2"></schart> |
|||
</div> |
|||
<div class="schart-box"> |
|||
<div class="content-title">饼状图</div> |
|||
<schart class="schart" canvasId="pie" :options="options3"></schart> |
|||
</div> |
|||
<div class="schart-box"> |
|||
<div class="content-title">环形图</div> |
|||
<schart class="schart" canvasId="ring" :options="options4"></schart> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import Schart from 'vue-schart'; |
|||
export default { |
|||
name: 'basecharts', |
|||
components: { |
|||
Schart |
|||
}, |
|||
data() { |
|||
return { |
|||
options1: { |
|||
type: 'bar', |
|||
title: { |
|||
text: '最近一周各品类销售图' |
|||
}, |
|||
bgColor: '#fbfbfb', |
|||
labels: ['周一', '周二', '周三', '周四', '周五'], |
|||
datasets: [ |
|||
{ |
|||
label: '家电', |
|||
fillColor: 'rgba(241, 49, 74, 0.5)', |
|||
data: [234, 278, 270, 190, 230] |
|||
}, |
|||
{ |
|||
label: '百货', |
|||
data: [164, 178, 190, 135, 160] |
|||
}, |
|||
{ |
|||
label: '食品', |
|||
data: [144, 198, 150, 235, 120] |
|||
} |
|||
] |
|||
}, |
|||
options2: { |
|||
type: 'line', |
|||
title: { |
|||
text: '最近几个月各品类销售趋势图' |
|||
}, |
|||
bgColor: '#fbfbfb', |
|||
labels: ['6月', '7月', '8月', '9月', '10月'], |
|||
datasets: [ |
|||
{ |
|||
label: '家电', |
|||
data: [234, 278, 270, 190, 230] |
|||
}, |
|||
{ |
|||
label: '百货', |
|||
data: [164, 178, 150, 135, 160] |
|||
}, |
|||
{ |
|||
label: '食品', |
|||
data: [114, 138, 200, 235, 190] |
|||
} |
|||
] |
|||
}, |
|||
options3: { |
|||
type: 'pie', |
|||
title: { |
|||
text: '服装品类销售饼状图' |
|||
}, |
|||
legend: { |
|||
position: 'left' |
|||
}, |
|||
bgColor: '#fbfbfb', |
|||
labels: ['T恤', '牛仔裤', '连衣裙', '毛衣', '七分裤', '短裙', '羽绒服'], |
|||
datasets: [ |
|||
{ |
|||
data: [334, 278, 190, 235, 260, 200, 141] |
|||
} |
|||
] |
|||
}, |
|||
options4: { |
|||
type: 'ring', |
|||
title: { |
|||
text: '环形三等分' |
|||
}, |
|||
showValue: false, |
|||
legend: { |
|||
position: 'bottom', |
|||
bottom: 40 |
|||
}, |
|||
bgColor: '#fbfbfb', |
|||
labels: ['vue', 'react', 'angular'], |
|||
datasets: [ |
|||
{ |
|||
data: [500, 500, 500] |
|||
} |
|||
] |
|||
} |
|||
}; |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.schart-box { |
|||
display: inline-block; |
|||
margin: 20px; |
|||
} |
|||
.schart { |
|||
width: 600px; |
|||
height: 400px; |
|||
} |
|||
.content-title { |
|||
clear: both; |
|||
font-weight: 400; |
|||
line-height: 50px; |
|||
margin: 10px 0; |
|||
font-size: 22px; |
|||
color: #1f2f3d; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,152 @@ |
|||
<template> |
|||
<div> |
|||
<div class="crumbs"> |
|||
<el-breadcrumb separator="/"> |
|||
<el-breadcrumb-item> |
|||
<i class="el-icon-lx-calendar"></i> 表单 |
|||
</el-breadcrumb-item> |
|||
<el-breadcrumb-item>基本表单</el-breadcrumb-item> |
|||
</el-breadcrumb> |
|||
</div> |
|||
<div class="container"> |
|||
<div class="form-box"> |
|||
<el-form ref="form" :model="form" label-width="80px"> |
|||
<el-form-item label="表单名称"> |
|||
<el-input v-model="form.name"></el-input> |
|||
</el-form-item> |
|||
<el-form-item label="选择器"> |
|||
<el-select v-model="form.region" placeholder="请选择"> |
|||
<el-option key="bbk" label="步步高" value="bbk"></el-option> |
|||
<el-option key="xtc" label="小天才" value="xtc"></el-option> |
|||
<el-option key="imoo" label="imoo" value="imoo"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="日期时间"> |
|||
<el-col :span="11"> |
|||
<el-date-picker |
|||
type="date" |
|||
placeholder="选择日期" |
|||
v-model="form.date1" |
|||
value-format="yyyy-MM-dd" |
|||
style="width: 100%;" |
|||
></el-date-picker> |
|||
</el-col> |
|||
<el-col class="line" :span="2">-</el-col> |
|||
<el-col :span="11"> |
|||
<el-time-picker |
|||
placeholder="选择时间" |
|||
v-model="form.date2" |
|||
style="width: 100%;" |
|||
></el-time-picker> |
|||
</el-col> |
|||
</el-form-item> |
|||
<el-form-item label="城市级联"> |
|||
<el-cascader :options="options" v-model="form.options"></el-cascader> |
|||
</el-form-item> |
|||
<el-form-item label="选择开关"> |
|||
<el-switch v-model="form.delivery"></el-switch> |
|||
</el-form-item> |
|||
<el-form-item label="多选框"> |
|||
<el-checkbox-group v-model="form.type"> |
|||
<el-checkbox label="步步高" name="type"></el-checkbox> |
|||
<el-checkbox label="小天才" name="type"></el-checkbox> |
|||
<el-checkbox label="imoo" name="type"></el-checkbox> |
|||
</el-checkbox-group> |
|||
</el-form-item> |
|||
<el-form-item label="单选框"> |
|||
<el-radio-group v-model="form.resource"> |
|||
<el-radio label="步步高"></el-radio> |
|||
<el-radio label="小天才"></el-radio> |
|||
<el-radio label="imoo"></el-radio> |
|||
</el-radio-group> |
|||
</el-form-item> |
|||
<el-form-item label="文本框"> |
|||
<el-input type="textarea" rows="5" v-model="form.desc"></el-input> |
|||
</el-form-item> |
|||
<el-form-item> |
|||
<el-button type="primary" @click="onSubmit">表单提交</el-button> |
|||
<el-button>取消</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'baseform', |
|||
data() { |
|||
return { |
|||
options: [ |
|||
{ |
|||
value: 'guangdong', |
|||
label: '广东省', |
|||
children: [ |
|||
{ |
|||
value: 'guangzhou', |
|||
label: '广州市', |
|||
children: [ |
|||
{ |
|||
value: 'tianhe', |
|||
label: '天河区' |
|||
}, |
|||
{ |
|||
value: 'haizhu', |
|||
label: '海珠区' |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
value: 'dongguan', |
|||
label: '东莞市', |
|||
children: [ |
|||
{ |
|||
value: 'changan', |
|||
label: '长安镇' |
|||
}, |
|||
{ |
|||
value: 'humen', |
|||
label: '虎门镇' |
|||
} |
|||
] |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
value: 'hunan', |
|||
label: '湖南省', |
|||
children: [ |
|||
{ |
|||
value: 'changsha', |
|||
label: '长沙市', |
|||
children: [ |
|||
{ |
|||
value: 'yuelu', |
|||
label: '岳麓区' |
|||
} |
|||
] |
|||
} |
|||
] |
|||
} |
|||
], |
|||
form: { |
|||
name: '', |
|||
region: '', |
|||
date1: '', |
|||
date2: '', |
|||
delivery: true, |
|||
type: ['步步高'], |
|||
resource: '小天才', |
|||
desc: '', |
|||
options: [] |
|||
} |
|||
}; |
|||
}, |
|||
methods: { |
|||
onSubmit() { |
|||
this.$message.success('提交成功!'); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
@ -0,0 +1,219 @@ |
|||
<template> |
|||
<div> |
|||
<div class="crumbs"> |
|||
<el-breadcrumb separator="/"> |
|||
<el-breadcrumb-item> |
|||
<i class="el-icon-lx-cascades"></i> 基础表格 |
|||
</el-breadcrumb-item> |
|||
</el-breadcrumb> |
|||
</div> |
|||
<div class="container"> |
|||
<div class="handle-box"> |
|||
<el-button |
|||
type="primary" |
|||
icon="el-icon-delete" |
|||
class="handle-del mr10" |
|||
@click="delAllSelection" |
|||
>批量删除</el-button> |
|||
<el-select v-model="query.address" placeholder="地址" class="handle-select mr10"> |
|||
<el-option key="1" label="广东省" value="广东省"></el-option> |
|||
<el-option key="2" label="湖南省" value="湖南省"></el-option> |
|||
</el-select> |
|||
<el-input v-model="query.name" placeholder="用户名" class="handle-input mr10"></el-input> |
|||
<el-button type="primary" icon="el-icon-search" @click="handleSearch">搜索</el-button> |
|||
</div> |
|||
<el-table |
|||
:data="tableData" |
|||
border |
|||
class="table" |
|||
ref="multipleTable" |
|||
header-cell-class-name="table-header" |
|||
@selection-change="handleSelectionChange" |
|||
> |
|||
<el-table-column type="selection" width="55" align="center"></el-table-column> |
|||
<el-table-column prop="id" label="ID" width="55" align="center"></el-table-column> |
|||
<el-table-column prop="name" label="用户名"></el-table-column> |
|||
<el-table-column label="账户余额"> |
|||
<template slot-scope="scope">¥{{scope.row.money}}</template> |
|||
</el-table-column> |
|||
<el-table-column label="头像(查看大图)" align="center"> |
|||
<template slot-scope="scope"> |
|||
<el-image |
|||
class="table-td-thumb" |
|||
:src="scope.row.thumb" |
|||
:preview-src-list="[scope.row.thumb]" |
|||
></el-image> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column prop="address" label="地址"></el-table-column> |
|||
<el-table-column label="状态" align="center"> |
|||
<template slot-scope="scope"> |
|||
<el-tag |
|||
:type="scope.row.state==='成功'?'success':(scope.row.state==='失败'?'danger':'')" |
|||
>{{scope.row.state}}</el-tag> |
|||
</template> |
|||
</el-table-column> |
|||
|
|||
<el-table-column prop="date" label="注册时间"></el-table-column> |
|||
<el-table-column label="操作" width="180" align="center"> |
|||
<template slot-scope="scope"> |
|||
<el-button |
|||
type="text" |
|||
icon="el-icon-edit" |
|||
@click="handleEdit(scope.$index, scope.row)" |
|||
>编辑</el-button> |
|||
<el-button |
|||
type="text" |
|||
icon="el-icon-delete" |
|||
class="red" |
|||
@click="handleDelete(scope.$index, scope.row)" |
|||
>删除</el-button> |
|||
</template> |
|||
</el-table-column> |
|||
</el-table> |
|||
<div class="pagination"> |
|||
<el-pagination |
|||
background |
|||
layout="total, prev, pager, next" |
|||
:current-page="query.pageIndex" |
|||
:page-size="query.pageSize" |
|||
:total="pageTotal" |
|||
@current-change="handlePageChange" |
|||
></el-pagination> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- 编辑弹出框 --> |
|||
<el-dialog title="编辑" :visible.sync="editVisible" width="30%"> |
|||
<el-form ref="form" :model="form" label-width="70px"> |
|||
<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> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import { fetchData } from '../../api/index'; |
|||
export default { |
|||
name: 'basetable', |
|||
data() { |
|||
return { |
|||
query: { |
|||
address: '', |
|||
name: '', |
|||
pageIndex: 1, |
|||
pageSize: 10 |
|||
}, |
|||
tableData: [], |
|||
multipleSelection: [], |
|||
delList: [], |
|||
editVisible: false, |
|||
pageTotal: 0, |
|||
form: {}, |
|||
idx: -1, |
|||
id: -1 |
|||
}; |
|||
}, |
|||
created() { |
|||
this.getData(); |
|||
}, |
|||
methods: { |
|||
// 获取 easy-mock 的模拟数据 |
|||
getData() { |
|||
fetchData(this.query).then(res => { |
|||
console.log(res); |
|||
this.tableData = res.list; |
|||
this.pageTotal = res.pageTotal || 50; |
|||
}); |
|||
}, |
|||
// 触发搜索按钮 |
|||
handleSearch() { |
|||
this.$set(this.query, 'pageIndex', 1); |
|||
this.getData(); |
|||
}, |
|||
// 删除操作 |
|||
handleDelete(index, row) { |
|||
// 二次确认删除 |
|||
this.$confirm('确定要删除吗?', '提示', { |
|||
type: 'warning' |
|||
}) |
|||
.then(() => { |
|||
this.$message.success('删除成功'); |
|||
this.tableData.splice(index, 1); |
|||
}) |
|||
.catch(() => {}); |
|||
}, |
|||
// 多选操作 |
|||
handleSelectionChange(val) { |
|||
this.multipleSelection = val; |
|||
}, |
|||
delAllSelection() { |
|||
const length = this.multipleSelection.length; |
|||
let str = ''; |
|||
this.delList = this.delList.concat(this.multipleSelection); |
|||
for (let i = 0; i < length; i++) { |
|||
str += this.multipleSelection[i].name + ' '; |
|||
} |
|||
this.$message.error(`删除了${str}`); |
|||
this.multipleSelection = []; |
|||
}, |
|||
// 编辑操作 |
|||
handleEdit(index, row) { |
|||
this.idx = index; |
|||
this.form = row; |
|||
this.editVisible = true; |
|||
}, |
|||
// 保存编辑 |
|||
saveEdit() { |
|||
this.editVisible = false; |
|||
this.$message.success(`修改第 ${this.idx + 1} 行成功`); |
|||
this.$set(this.tableData, this.idx, this.form); |
|||
}, |
|||
// 分页导航 |
|||
handlePageChange(val) { |
|||
this.$set(this.query, 'pageIndex', val); |
|||
this.getData(); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.handle-box { |
|||
margin-bottom: 20px; |
|||
} |
|||
|
|||
.handle-select { |
|||
width: 120px; |
|||
} |
|||
|
|||
.handle-input { |
|||
width: 300px; |
|||
display: inline-block; |
|||
} |
|||
.table { |
|||
width: 100%; |
|||
font-size: 14px; |
|||
} |
|||
.red { |
|||
color: #ff0000; |
|||
} |
|||
.mr10 { |
|||
margin-right: 10px; |
|||
} |
|||
.table-td-thumb { |
|||
display: block; |
|||
margin: auto; |
|||
width: 40px; |
|||
height: 40px; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,376 @@ |
|||
<template> |
|||
<div> |
|||
<el-row :gutter="20"> |
|||
<el-col :span="8"> |
|||
<el-card shadow="hover" class="mgb20" style="height:252px;"> |
|||
<div class="user-info"> |
|||
<img src="../../assets/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>2019-11-01</span> |
|||
</div> |
|||
<div class="user-info-list"> |
|||
上次登录地点: |
|||
<span>东莞</span> |
|||
</div> |
|||
</el-card> |
|||
<el-card shadow="hover" style="height:252px;"> |
|||
<div slot="header" class="clearfix"> |
|||
<span>语言详情</span> |
|||
</div>Vue |
|||
<el-progress :percentage="71.3" color="#42b983"></el-progress>JavaScript |
|||
<el-progress :percentage="24.1" color="#f1e05a"></el-progress>CSS |
|||
<el-progress :percentage="13.7"></el-progress>HTML |
|||
<el-progress :percentage="5.9" color="#f56c6c"></el-progress> |
|||
</el-card> |
|||
</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-lx-people 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-lx-notice 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-lx-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" style="height:403px;"> |
|||
<div slot="header" class="clearfix"> |
|||
<span>待办事项</span> |
|||
<el-button style="float: right; padding: 3px 0" type="text">添加</el-button> |
|||
</div> |
|||
<el-table :show-header="false" :data="todoList" style="width:100%;"> |
|||
<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> |
|||
<i class="el-icon-edit"></i> |
|||
<i class="el-icon-delete"></i> |
|||
</template> |
|||
</el-table-column> |
|||
</el-table> |
|||
</el-card> |
|||
</el-col> |
|||
</el-row> |
|||
<el-row :gutter="20"> |
|||
<el-col :span="12"> |
|||
<el-card shadow="hover"> |
|||
<schart ref="bar" class="schart" canvasId="bar" :options="options"></schart> |
|||
</el-card> |
|||
</el-col> |
|||
<el-col :span="12"> |
|||
<el-card shadow="hover"> |
|||
<schart ref="line" class="schart" canvasId="line" :options="options2"></schart> |
|||
</el-card> |
|||
</el-col> |
|||
</el-row> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import Schart from 'vue-schart'; |
|||
import bus from '../common/bus'; |
|||
export default { |
|||
name: 'dashboard', |
|||
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 |
|||
} |
|||
], |
|||
data: [ |
|||
{ |
|||
name: '2018/09/04', |
|||
value: 1083 |
|||
}, |
|||
{ |
|||
name: '2018/09/05', |
|||
value: 941 |
|||
}, |
|||
{ |
|||
name: '2018/09/06', |
|||
value: 1139 |
|||
}, |
|||
{ |
|||
name: '2018/09/07', |
|||
value: 816 |
|||
}, |
|||
{ |
|||
name: '2018/09/08', |
|||
value: 327 |
|||
}, |
|||
{ |
|||
name: '2018/09/09', |
|||
value: 228 |
|||
}, |
|||
{ |
|||
name: '2018/09/10', |
|||
value: 1065 |
|||
} |
|||
], |
|||
options: { |
|||
type: 'bar', |
|||
title: { |
|||
text: '最近一周各品类销售图' |
|||
}, |
|||
xRorate: 25, |
|||
labels: ['周一', '周二', '周三', '周四', '周五'], |
|||
datasets: [ |
|||
{ |
|||
label: '家电', |
|||
data: [234, 278, 270, 190, 230] |
|||
}, |
|||
{ |
|||
label: '百货', |
|||
data: [164, 178, 190, 135, 160] |
|||
}, |
|||
{ |
|||
label: '食品', |
|||
data: [144, 198, 150, 235, 120] |
|||
} |
|||
] |
|||
}, |
|||
options2: { |
|||
type: 'line', |
|||
title: { |
|||
text: '最近几个月各品类销售趋势图' |
|||
}, |
|||
labels: ['6月', '7月', '8月', '9月', '10月'], |
|||
datasets: [ |
|||
{ |
|||
label: '家电', |
|||
data: [234, 278, 270, 190, 230] |
|||
}, |
|||
{ |
|||
label: '百货', |
|||
data: [164, 178, 150, 135, 160] |
|||
}, |
|||
{ |
|||
label: '食品', |
|||
data: [74, 118, 200, 235, 90] |
|||
} |
|||
] |
|||
} |
|||
}; |
|||
}, |
|||
components: { |
|||
Schart |
|||
}, |
|||
computed: { |
|||
role() { |
|||
return this.name === 'admin' ? '超级管理员' : '普通用户'; |
|||
} |
|||
}, |
|||
// created() { |
|||
// this.handleListener(); |
|||
// this.changeDate(); |
|||
// }, |
|||
// activated() { |
|||
// this.handleListener(); |
|||
// }, |
|||
// deactivated() { |
|||
// window.removeEventListener('resize', this.renderChart); |
|||
// bus.$off('collapse', this.handleBus); |
|||
// }, |
|||
methods: { |
|||
changeDate() { |
|||
const now = new Date().getTime(); |
|||
this.data.forEach((item, index) => { |
|||
const date = new Date(now - (6 - index) * 86400000); |
|||
item.name = `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`; |
|||
}); |
|||
} |
|||
// handleListener() { |
|||
// bus.$on('collapse', this.handleBus); |
|||
// // 调用renderChart方法对图表进行重新渲染 |
|||
// window.addEventListener('resize', this.renderChart); |
|||
// }, |
|||
// handleBus(msg) { |
|||
// setTimeout(() => { |
|||
// this.renderChart(); |
|||
// }, 200); |
|||
// }, |
|||
// renderChart() { |
|||
// this.$refs.bar.renderChart(); |
|||
// this.$refs.line.renderChart(); |
|||
// } |
|||
} |
|||
}; |
|||
</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: 14px; |
|||
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; |
|||
} |
|||
|
|||
.schart { |
|||
width: 100%; |
|||
height: 300px; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,24 @@ |
|||
<template> |
|||
<div> |
|||
<div class="crumbs"> |
|||
<el-breadcrumb separator="/"> |
|||
<el-breadcrumb-item> |
|||
<i class="el-icon-lx-redpacket_fill"></i> 支持作者 |
|||
</el-breadcrumb-item> |
|||
</el-breadcrumb> |
|||
</div> |
|||
<div class="container"> |
|||
<div class="plugins-tips">如果该框架对你有帮助,那就请作者喝杯饮料吧!加微信号linxin_20探讨问题。</div> |
|||
<div> |
|||
<img src="https://lin-xin.gitee.io/images/weixin.jpg" /> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default {}; |
|||
</script> |
|||
|
|||
<style> |
|||
</style> |
|||
@ -0,0 +1,36 @@ |
|||
<template> |
|||
<section class="main"> |
|||
<div class="crumbs"> |
|||
<el-breadcrumb separator="/"> |
|||
<el-breadcrumb-item><i class="el-icon-rank"></i> 拖拽组件</el-breadcrumb-item> |
|||
<el-breadcrumb-item>拖拽弹框</el-breadcrumb-item> |
|||
</el-breadcrumb> |
|||
</div> |
|||
<div class="container"> |
|||
<p>通过指令 v-dialogDrag 使 Dialog 对话框具有可拖拽的功能。</p> |
|||
<br> |
|||
<el-button type="primary" @click="visible = true;">点我弹框</el-button> |
|||
</div> |
|||
<el-dialog v-dialogDrag title="拖拽弹框" center :visible.sync="visible" width="30%"> |
|||
我是一个可以拖拽的对话框! |
|||
<span slot="footer" class="dialog-footer"> |
|||
<el-button @click="visible = false">取 消</el-button> |
|||
<el-button type="primary" @click="visible = false">确 定</el-button> |
|||
</span> |
|||
</el-dialog> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data(){ |
|||
return { |
|||
visible: false |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style> |
|||
|
|||
</style> |
|||
@ -0,0 +1,174 @@ |
|||
<template> |
|||
<section class="main"> |
|||
<div class="crumbs"> |
|||
<el-breadcrumb separator="/"> |
|||
<el-breadcrumb-item><i class="el-icon-rank"></i> 拖拽组件</el-breadcrumb-item> |
|||
<el-breadcrumb-item>拖拽排序</el-breadcrumb-item> |
|||
</el-breadcrumb> |
|||
</div> |
|||
<div class="container"> |
|||
<div class="plugins-tips"> |
|||
Vue.Draggable:基于 Sortable.js 的 Vue 拖拽组件。 |
|||
访问地址:<a href="https://github.com/SortableJS/Vue.Draggable" target="_blank">Vue.Draggable</a> |
|||
</div> |
|||
<div class="drag-box"> |
|||
<div class="drag-box-item"> |
|||
<div class="item-title">todo</div> |
|||
<draggable v-model="todo" @remove="removeHandle" :options="dragOptions"> |
|||
<transition-group tag="div" id="todo" class="item-ul"> |
|||
<div v-for="item in todo" class="drag-list" :key="item.id"> |
|||
{{item.content}} |
|||
</div> |
|||
</transition-group> |
|||
</draggable> |
|||
</div> |
|||
<div class="drag-box-item"> |
|||
<div class="item-title">doing</div> |
|||
<draggable v-model="doing" @remove="removeHandle" :options="dragOptions"> |
|||
<transition-group tag="div" id="doing" class="item-ul"> |
|||
<div v-for="item in doing" class="drag-list" :key="item.id"> |
|||
{{item.content}} |
|||
</div> |
|||
</transition-group> |
|||
</draggable> |
|||
</div> |
|||
<div class="drag-box-item"> |
|||
<div class="item-title">done</div> |
|||
<draggable v-model="done" @remove="removeHandle" :options="dragOptions"> |
|||
<transition-group tag="div" id="done" class="item-ul"> |
|||
<div v-for="item in done" class="drag-list" :key="item.id"> |
|||
{{item.content}} |
|||
</div> |
|||
</transition-group> |
|||
</draggable> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
import draggable from 'vuedraggable' |
|||
export default { |
|||
name: 'draglist', |
|||
data() { |
|||
return { |
|||
dragOptions:{ |
|||
animation: 120, |
|||
scroll: true, |
|||
group: 'sortlist', |
|||
ghostClass: 'ghost-style' |
|||
}, |
|||
todo: [ |
|||
{ |
|||
id: 1, |
|||
content: '开发图表组件' |
|||
}, |
|||
{ |
|||
id: 2, |
|||
content: '开发拖拽组件' |
|||
}, |
|||
{ |
|||
id: 3, |
|||
content: '开发权限测试组件' |
|||
} |
|||
], |
|||
doing: [ |
|||
{ |
|||
id: 1, |
|||
content: '开发登录注册页面' |
|||
}, |
|||
{ |
|||
id: 2, |
|||
content: '开发头部组件' |
|||
}, |
|||
{ |
|||
id: 3, |
|||
content: '开发表格相关组件' |
|||
}, |
|||
{ |
|||
id: 4, |
|||
content: '开发表单相关组件' |
|||
} |
|||
], |
|||
done:[ |
|||
{ |
|||
id: 1, |
|||
content: '初始化项目,生成工程目录,完成相关配置' |
|||
}, |
|||
{ |
|||
id: 2, |
|||
content: '开发项目整体框架' |
|||
} |
|||
] |
|||
} |
|||
}, |
|||
components:{ |
|||
draggable |
|||
}, |
|||
methods: { |
|||
removeHandle(event){ |
|||
console.log(event); |
|||
this.$message.success(`从 ${event.from.id} 移动到 ${event.to.id} `); |
|||
} |
|||
} |
|||
} |
|||
|
|||
</script> |
|||
|
|||
<style scoped> |
|||
.drag-box{ |
|||
display: flex; |
|||
user-select: none; |
|||
} |
|||
.drag-box-item { |
|||
flex: 1; |
|||
max-width: 330px; |
|||
min-width: 300px; |
|||
background-color: #eff1f5; |
|||
margin-right: 16px; |
|||
border-radius: 6px; |
|||
border: 1px #e1e4e8 solid; |
|||
} |
|||
.item-title{ |
|||
padding: 8px 8px 8px 12px; |
|||
font-size: 14px; |
|||
line-height: 1.5; |
|||
color: #24292e; |
|||
font-weight: 600; |
|||
} |
|||
.item-ul{ |
|||
padding: 0 8px 8px; |
|||
height: 500px; |
|||
overflow-y: scroll; |
|||
} |
|||
.item-ul::-webkit-scrollbar{ |
|||
width: 0; |
|||
} |
|||
.drag-list { |
|||
border: 1px #e1e4e8 solid; |
|||
padding: 10px; |
|||
margin: 5px 0 10px; |
|||
list-style: none; |
|||
background-color: #fff; |
|||
border-radius: 6px; |
|||
cursor: pointer; |
|||
-webkit-transition: border .3s ease-in; |
|||
transition: border .3s ease-in; |
|||
} |
|||
.drag-list:hover { |
|||
border: 1px solid #20a0ff; |
|||
} |
|||
.drag-title { |
|||
font-weight: 400; |
|||
line-height: 25px; |
|||
margin: 10px 0; |
|||
font-size: 22px; |
|||
color: #1f2f3d; |
|||
} |
|||
.ghost-style{ |
|||
display: block; |
|||
color: transparent; |
|||
border-style: dashed |
|||
} |
|||
</style> |
|||
@ -0,0 +1,46 @@ |
|||
<template> |
|||
<section class="main"> |
|||
<div class="crumbs"> |
|||
<el-breadcrumb separator="/"> |
|||
<el-breadcrumb-item><i class="el-icon-lx-global"></i> {{$t('i18n.breadcrumb')}}</el-breadcrumb-item> |
|||
</el-breadcrumb> |
|||
</div> |
|||
<div class="container"> |
|||
<span>{{$t('i18n.tips')}}</span> |
|||
<el-button type="primary" @click="$i18n.locale = $i18n.locale === 'zh'?'en':'zh';">{{$t('i18n.btn')}}</el-button> |
|||
<div class="list"> |
|||
<h2>{{$t('i18n.title1')}}</h2> |
|||
<p>{{$t('i18n.p1')}}</p> |
|||
<p>{{$t('i18n.p2')}}</p> |
|||
<p>{{$t('i18n.p3')}}</p> |
|||
</div> |
|||
<h2>{{$t('i18n.title2')}}</h2> |
|||
<div> |
|||
<i18n path="i18n.info" tag="p"> |
|||
<a place="action" href="https://element.eleme.cn/2.0/#/zh-CN/component/i18n">{{ $t('i18n.value') }}</a> |
|||
</i18n> |
|||
</div> |
|||
</div> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data(){ |
|||
return { |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.list{ |
|||
padding: 30px 0; |
|||
} |
|||
.list p{ |
|||
margin-bottom: 20px; |
|||
} |
|||
a{ |
|||
color: #409eff; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,225 @@ |
|||
<template> |
|||
<div> |
|||
<div class="crumbs"> |
|||
<el-breadcrumb separator="/"> |
|||
<el-breadcrumb-item><i class="el-icon-lx-emoji"></i> 自定义图标</el-breadcrumb-item> |
|||
</el-breadcrumb> |
|||
</div> |
|||
<div class="container"> |
|||
<h2>使用方法</h2> |
|||
<p style="line-height: 50px;"> |
|||
直接通过设置类名为 el-icon-lx-iconName 来使用即可。例如:(共{{iconList.length}}个图标) |
|||
</p> |
|||
<p class="example-p"> |
|||
<i class="el-icon-lx-redpacket_fill" style="font-size: 30px;color: #ff5900"></i> |
|||
<span><i class="el-icon-lx-redpacket_fill"></i></span> |
|||
</p> |
|||
<p class="example-p"> |
|||
<i class="el-icon-lx-weibo" style="font-size: 30px;color:#fd5656"></i> |
|||
<span><i class="el-icon-lx-weibo"></i></span> |
|||
</p> |
|||
<p class="example-p"> |
|||
<i class="el-icon-lx-emojifill" style="font-size: 30px;color: #ffc300"></i> |
|||
<span><i class="el-icon-lx-emojifill"></i></span> |
|||
</p> |
|||
<br> |
|||
<h2>图标</h2> |
|||
<div class="search-box"> |
|||
<el-input class="search" size="large" v-model="keyword" clearable placeholder="请输入图标名称"></el-input> |
|||
</div> |
|||
<ul> |
|||
<li class="icon-li" v-for="(item,index) in list" :key="index"> |
|||
<div class="icon-li-content"> |
|||
<i :class="`el-icon-lx-${item}`"></i> |
|||
<span>{{item}}</span> |
|||
</div> |
|||
</li> |
|||
</ul> |
|||
</div> |
|||
|
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data: function(){ |
|||
return { |
|||
keyword: '', |
|||
iconList: [ |
|||
'attentionforbid', |
|||
'attentionforbidfill', |
|||
'attention', |
|||
'attentionfill', |
|||
'tag', |
|||
'tagfill', |
|||
'people', |
|||
'peoplefill', |
|||
'notice', |
|||
'noticefill', |
|||
'mobile', |
|||
'mobilefill', |
|||
'voice', |
|||
'voicefill', |
|||
'unlock', |
|||
'lock', |
|||
'home', |
|||
'homefill', |
|||
'delete', |
|||
'deletefill', |
|||
'notification', |
|||
'notificationfill', |
|||
'notificationforbidfill', |
|||
'like', |
|||
'likefill', |
|||
'comment', |
|||
'commentfill', |
|||
'camera', |
|||
'camerafill', |
|||
'warn', |
|||
'warnfill', |
|||
'time', |
|||
'timefill', |
|||
'location', |
|||
'locationfill', |
|||
'favor', |
|||
'favorfill', |
|||
'skin', |
|||
'skinfill', |
|||
'news', |
|||
'newsfill', |
|||
'record', |
|||
'recordfill', |
|||
'emoji', |
|||
'emojifill', |
|||
'message', |
|||
'messagefill', |
|||
'goods', |
|||
'goodsfill', |
|||
'crown', |
|||
'crownfill', |
|||
'move', |
|||
'add', |
|||
'hot', |
|||
'hotfill', |
|||
'service', |
|||
'servicefill', |
|||
'present', |
|||
'presentfill', |
|||
'pic', |
|||
'picfill', |
|||
'rank', |
|||
'rankfill', |
|||
'male', |
|||
'female', |
|||
'down', |
|||
'top', |
|||
'recharge', |
|||
'rechargefill', |
|||
'forward', |
|||
'forwardfill', |
|||
'info', |
|||
'infofill', |
|||
'redpacket', |
|||
'redpacket_fill', |
|||
'roundadd', |
|||
'roundaddfill', |
|||
'friendadd', |
|||
'friendaddfill', |
|||
'cart', |
|||
'cartfill', |
|||
'more', |
|||
'moreandroid', |
|||
'back', |
|||
'right', |
|||
'shop', |
|||
'shopfill', |
|||
'question', |
|||
'questionfill', |
|||
'roundclose', |
|||
'roundclosefill', |
|||
'roundcheck', |
|||
'roundcheckfill', |
|||
'global', |
|||
'mail', |
|||
'punch', |
|||
'exit', |
|||
'upload', |
|||
'read', |
|||
'file', |
|||
'link', |
|||
'full', |
|||
'group', |
|||
'friend', |
|||
'profile', |
|||
'addressbook', |
|||
'calendar', |
|||
'text', |
|||
'copy', |
|||
'share', |
|||
'wifi', |
|||
'vipcard', |
|||
'weibo', |
|||
'remind', |
|||
'refresh', |
|||
'filter', |
|||
'settings', |
|||
'scan', |
|||
'qrcode', |
|||
'cascades', |
|||
'apps', |
|||
'sort', |
|||
'searchlist', |
|||
'search', |
|||
'edit' |
|||
] |
|||
} |
|||
}, |
|||
computed: { |
|||
list(){ |
|||
return this.iconList.filter((item) => { |
|||
return item.indexOf(this.keyword) !== -1; |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.example-p{ |
|||
height: 45px; |
|||
display: flex; |
|||
align-items: center; |
|||
} |
|||
.search-box{ |
|||
text-align: center; |
|||
margin-top: 10px; |
|||
} |
|||
.search{ |
|||
width: 300px; |
|||
} |
|||
ul,li{ |
|||
list-style: none; |
|||
} |
|||
.icon-li{ |
|||
display: inline-block; |
|||
padding: 10px; |
|||
width: 120px; |
|||
height: 120px; |
|||
} |
|||
.icon-li-content{ |
|||
display: flex; |
|||
height: 100%; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: center; |
|||
cursor: pointer; |
|||
} |
|||
.icon-li-content i{ |
|||
font-size: 36px; |
|||
color: #606266; |
|||
} |
|||
.icon-li-content span{ |
|||
margin-top: 10px; |
|||
color: #787878; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,104 @@ |
|||
<template> |
|||
<div class="login-wrap"> |
|||
<div class="ms-login"> |
|||
<div class="ms-title">后台管理系统</div> |
|||
<el-form :model="param" :rules="rules" ref="login" label-width="0px" class="ms-content"> |
|||
<el-form-item prop="username"> |
|||
<el-input v-model="param.username" placeholder="username"> |
|||
<el-button slot="prepend" icon="el-icon-lx-people"></el-button> |
|||
</el-input> |
|||
</el-form-item> |
|||
<el-form-item prop="password"> |
|||
<el-input |
|||
type="password" |
|||
placeholder="password" |
|||
v-model="param.password" |
|||
@keyup.enter.native="submitForm()" |
|||
> |
|||
<el-button slot="prepend" icon="el-icon-lx-lock"></el-button> |
|||
</el-input> |
|||
</el-form-item> |
|||
<div class="login-btn"> |
|||
<el-button type="primary" @click="submitForm()">登录</el-button> |
|||
</div> |
|||
<p class="login-tips">Tips : 用户名和密码随便填。</p> |
|||
</el-form> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data: function() { |
|||
return { |
|||
param: { |
|||
username: 'admin', |
|||
password: '123123', |
|||
}, |
|||
rules: { |
|||
username: [{ required: true, message: '请输入用户名', trigger: 'blur' }], |
|||
password: [{ required: true, message: '请输入密码', trigger: 'blur' }], |
|||
}, |
|||
}; |
|||
}, |
|||
methods: { |
|||
submitForm() { |
|||
this.$refs.login.validate(valid => { |
|||
if (valid) { |
|||
this.$message.success('登录成功'); |
|||
localStorage.setItem('ms_username', this.param.username); |
|||
this.$router.push('/'); |
|||
} else { |
|||
this.$message.error('请输入账号和密码'); |
|||
console.log('error submit!!'); |
|||
return false; |
|||
} |
|||
}); |
|||
}, |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.login-wrap { |
|||
position: relative; |
|||
width: 100%; |
|||
height: 100%; |
|||
background-image: url(../../assets/img/login-bg.jpg); |
|||
background-size: 100%; |
|||
} |
|||
.ms-title { |
|||
width: 100%; |
|||
line-height: 50px; |
|||
text-align: center; |
|||
font-size: 20px; |
|||
color: #fff; |
|||
border-bottom: 1px solid #ddd; |
|||
} |
|||
.ms-login { |
|||
position: absolute; |
|||
left: 50%; |
|||
top: 50%; |
|||
width: 350px; |
|||
margin: -190px 0 0 -175px; |
|||
border-radius: 5px; |
|||
background: rgba(255, 255, 255, 0.3); |
|||
overflow: hidden; |
|||
} |
|||
.ms-content { |
|||
padding: 30px 30px; |
|||
} |
|||
.login-btn { |
|||
text-align: center; |
|||
} |
|||
.login-btn button { |
|||
width: 100%; |
|||
height: 36px; |
|||
margin-bottom: 10px; |
|||
} |
|||
.login-tips { |
|||
font-size: 12px; |
|||
line-height: 30px; |
|||
color: #fff; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,67 @@ |
|||
<template> |
|||
<div> |
|||
<div class="crumbs"> |
|||
<el-breadcrumb separator="/"> |
|||
<el-breadcrumb-item><i class="el-icon-lx-calendar"></i> 表单</el-breadcrumb-item> |
|||
<el-breadcrumb-item>markdown编辑器</el-breadcrumb-item> |
|||
</el-breadcrumb> |
|||
</div> |
|||
<div class="container"> |
|||
<div class="plugins-tips"> |
|||
mavonEditor:基于Vue的markdown编辑器。 |
|||
访问地址:<a href="https://github.com/hinesboy/mavonEditor" target="_blank">mavonEditor</a> |
|||
</div> |
|||
<mavon-editor v-model="content" ref="md" @imgAdd="$imgAdd" @change="change" style="min-height: 600px"/> |
|||
<el-button class="editor-btn" type="primary" @click="submit">提交</el-button> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import { mavonEditor } from 'mavon-editor' |
|||
import 'mavon-editor/dist/css/index.css' |
|||
export default { |
|||
name: 'markdown', |
|||
data: function(){ |
|||
return { |
|||
content:'', |
|||
html:'', |
|||
configs: { |
|||
} |
|||
} |
|||
}, |
|||
components: { |
|||
mavonEditor |
|||
}, |
|||
methods: { |
|||
// 将图片上传到服务器,返回地址替换到md中 |
|||
$imgAdd(pos, $file){ |
|||
var formdata = new FormData(); |
|||
formdata.append('file', $file); |
|||
// 这里没有服务器供大家尝试,可将下面上传接口替换为你自己的服务器接口 |
|||
this.$axios({ |
|||
url: '/common/upload', |
|||
method: 'post', |
|||
data: formdata, |
|||
headers: { 'Content-Type': 'multipart/form-data' }, |
|||
}).then((url) => { |
|||
this.$refs.md.$img2Url(pos, url); |
|||
}) |
|||
}, |
|||
change(value, render){ |
|||
// render 为 markdown 解析后的结果 |
|||
this.html = render; |
|||
}, |
|||
submit(){ |
|||
console.log(this.content); |
|||
console.log(this.html); |
|||
this.$message.success('提交成功!'); |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
<style scoped> |
|||
.editor-btn{ |
|||
margin-top: 20px; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,38 @@ |
|||
<template> |
|||
<div> |
|||
<div class="crumbs"> |
|||
<el-breadcrumb separator="/"> |
|||
<el-breadcrumb-item><i class="el-icon-lx-warn"></i> 权限测试</el-breadcrumb-item> |
|||
</el-breadcrumb> |
|||
</div> |
|||
<div class="container"> |
|||
<h1>管理员权限页面</h1> |
|||
<p>只有用 admin 账号登录的才拥有管理员权限,才能进到这个页面,其他账号想进来都会跳到403页面,重新用管理员账号登录才有权限。</p> |
|||
<p>想尝试一下,请<router-link to="/login" class="logout">退出登录</router-link>,随便输入个账号名,再进来试试看。</p> |
|||
</div> |
|||
|
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data: function(){ |
|||
return {} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
h1{ |
|||
text-align: center; |
|||
margin: 30px 0; |
|||
} |
|||
p{ |
|||
line-height: 30px; |
|||
margin-bottom: 10px; |
|||
text-indent: 2em; |
|||
} |
|||
.logout{ |
|||
color: #409EFF; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,129 @@ |
|||
<template> |
|||
<div class=""> |
|||
<div class="crumbs"> |
|||
<el-breadcrumb separator="/"> |
|||
<el-breadcrumb-item><i class="el-icon-lx-copy"></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 { |
|||
name: 'tabs', |
|||
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> |
|||
|
|||
@ -0,0 +1,141 @@ |
|||
<template> |
|||
<div> |
|||
<div class="crumbs"> |
|||
<el-breadcrumb separator="/"> |
|||
<el-breadcrumb-item><i class="el-icon-lx-calendar"></i> 表单</el-breadcrumb-item> |
|||
<el-breadcrumb-item>图片上传</el-breadcrumb-item> |
|||
</el-breadcrumb> |
|||
</div> |
|||
<div class="container"> |
|||
<div class="content-title">支持拖拽</div> |
|||
<div class="plugins-tips"> |
|||
Element UI自带上传组件。 |
|||
访问地址:<a href="http://element.eleme.io/#/zh-CN/component/upload" target="_blank">Element UI Upload</a> |
|||
</div> |
|||
<el-upload |
|||
class="upload-demo" |
|||
drag |
|||
action="http://jsonplaceholder.typicode.com/api/posts/" |
|||
multiple> |
|||
<i class="el-icon-upload"></i> |
|||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div> |
|||
<div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div> |
|||
</el-upload> |
|||
<div class="content-title">支持裁剪</div> |
|||
<div class="plugins-tips"> |
|||
vue-cropperjs:一个封装了 cropperjs 的 Vue 组件。 |
|||
访问地址:<a href="https://github.com/Agontuk/vue-cropperjs" target="_blank">vue-cropperjs</a> |
|||
</div> |
|||
<div class="crop-demo"> |
|||
<img :src="cropImg" class="pre-img"> |
|||
<div class="crop-demo-btn">选择图片 |
|||
<input class="crop-input" type="file" name="image" accept="image/*" @change="setImage"/> |
|||
</div> |
|||
</div> |
|||
|
|||
<el-dialog title="裁剪图片" :visible.sync="dialogVisible" width="30%"> |
|||
<vue-cropper ref='cropper' :src="imgSrc" :ready="cropImage" :zoom="cropImage" :cropmove="cropImage" style="width:100%;height:300px;"></vue-cropper> |
|||
<span slot="footer" class="dialog-footer"> |
|||
<el-button @click="cancelCrop">取 消</el-button> |
|||
<el-button type="primary" @click="dialogVisible = false">确 定</el-button> |
|||
</span> |
|||
</el-dialog> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import VueCropper from 'vue-cropperjs'; |
|||
export default { |
|||
name: 'upload', |
|||
data: function(){ |
|||
return { |
|||
defaultSrc: require('../../assets/img/img.jpg'), |
|||
fileList: [], |
|||
imgSrc: '', |
|||
cropImg: '', |
|||
dialogVisible: false, |
|||
} |
|||
}, |
|||
components: { |
|||
VueCropper |
|||
}, |
|||
methods:{ |
|||
setImage(e){ |
|||
const file = e.target.files[0]; |
|||
if (!file.type.includes('image/')) { |
|||
return; |
|||
} |
|||
const reader = new FileReader(); |
|||
reader.onload = (event) => { |
|||
this.dialogVisible = true; |
|||
this.imgSrc = event.target.result; |
|||
this.$refs.cropper && this.$refs.cropper.replace(event.target.result); |
|||
}; |
|||
reader.readAsDataURL(file); |
|||
}, |
|||
cropImage () { |
|||
this.cropImg = this.$refs.cropper.getCroppedCanvas().toDataURL(); |
|||
}, |
|||
cancelCrop(){ |
|||
this.dialogVisible = false; |
|||
this.cropImg = this.defaultSrc; |
|||
}, |
|||
imageuploaded(res) { |
|||
console.log(res) |
|||
}, |
|||
handleError(){ |
|||
this.$notify.error({ |
|||
title: '上传失败', |
|||
message: '图片上传接口上传失败,可更改为自己的服务器接口' |
|||
}); |
|||
} |
|||
}, |
|||
created(){ |
|||
this.cropImg = this.defaultSrc; |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.content-title{ |
|||
font-weight: 400; |
|||
line-height: 50px; |
|||
margin: 10px 0; |
|||
font-size: 22px; |
|||
color: #1f2f3d; |
|||
} |
|||
.pre-img{ |
|||
width: 100px; |
|||
height: 100px; |
|||
background: #f8f8f8; |
|||
border: 1px solid #eee; |
|||
border-radius: 5px; |
|||
} |
|||
.crop-demo{ |
|||
display: flex; |
|||
align-items: flex-end; |
|||
} |
|||
.crop-demo-btn{ |
|||
position: relative; |
|||
width: 100px; |
|||
height: 40px; |
|||
line-height: 40px; |
|||
padding: 0 20px; |
|||
margin-left: 30px; |
|||
background-color: #409eff; |
|||
color: #fff; |
|||
font-size: 14px; |
|||
border-radius: 4px; |
|||
box-sizing: border-box; |
|||
} |
|||
.crop-input{ |
|||
position: absolute; |
|||
width: 100px; |
|||
height: 40px; |
|||
left: 0; |
|||
top: 0; |
|||
opacity: 0; |
|||
cursor: pointer; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,53 @@ |
|||
<template> |
|||
<div> |
|||
<div class="crumbs"> |
|||
<el-breadcrumb separator="/"> |
|||
<el-breadcrumb-item><i class="el-icon-lx-calendar"></i> 表单</el-breadcrumb-item> |
|||
<el-breadcrumb-item>编辑器</el-breadcrumb-item> |
|||
</el-breadcrumb> |
|||
</div> |
|||
<div class="container"> |
|||
<div class="plugins-tips"> |
|||
Vue-Quill-Editor:基于Quill、适用于Vue2的富文本编辑器。 |
|||
访问地址:<a href="https://github.com/surmon-china/vue-quill-editor" target="_blank">vue-quill-editor</a> |
|||
</div> |
|||
<quill-editor ref="myTextEditor" v-model="content" :options="editorOption"></quill-editor> |
|||
<el-button class="editor-btn" type="primary" @click="submit">提交</el-button> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import 'quill/dist/quill.core.css'; |
|||
import 'quill/dist/quill.snow.css'; |
|||
import 'quill/dist/quill.bubble.css'; |
|||
import { quillEditor } from 'vue-quill-editor'; |
|||
export default { |
|||
name: 'editor', |
|||
data: function(){ |
|||
return { |
|||
content: '', |
|||
editorOption: { |
|||
placeholder: 'Hello World' |
|||
} |
|||
} |
|||
}, |
|||
components: { |
|||
quillEditor |
|||
}, |
|||
methods: { |
|||
onEditorChange({ editor, html, text }) { |
|||
this.content = html; |
|||
}, |
|||
submit(){ |
|||
console.log(this.content); |
|||
this.$message.success('提交成功!'); |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
<style scoped> |
|||
.editor-btn{ |
|||
margin-top: 20px; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,48 @@ |
|||
import Vue from 'vue'; |
|||
import App from './App.vue'; |
|||
import router from './router'; |
|||
import ElementUI from 'element-ui'; |
|||
import VueI18n from 'vue-i18n'; |
|||
import { messages } from './components/common/i18n'; |
|||
import 'element-ui/lib/theme-chalk/index.css'; // 默认主题
|
|||
// import './assets/css/theme-green/index.css'; // 浅绿色主题
|
|||
import './assets/css/icon.css'; |
|||
import './components/common/directives'; |
|||
import 'babel-polyfill'; |
|||
|
|||
Vue.config.productionTip = false; |
|||
Vue.use(VueI18n); |
|||
Vue.use(ElementUI, { |
|||
size: 'small' |
|||
}); |
|||
const i18n = new VueI18n({ |
|||
locale: 'zh', |
|||
messages |
|||
}); |
|||
|
|||
//使用钩子函数对路由进行权限跳转
|
|||
router.beforeEach((to, from, next) => { |
|||
document.title = `${to.meta.title} | vue-manage-system`; |
|||
const role = localStorage.getItem('ms_username'); |
|||
if (!role && to.path !== '/login') { |
|||
next('/login'); |
|||
} else if (to.meta.permission) { |
|||
// 如果是管理员权限则可进入,这里只是简单的模拟管理员权限而已
|
|||
role === 'admin' ? next() : next('/403'); |
|||
} else { |
|||
// 简单的判断IE10及以下不进入富文本编辑器,该组件不兼容
|
|||
if (navigator.userAgent.indexOf('MSIE') > -1 && to.path === '/editor') { |
|||
Vue.prototype.$alert('vue-quill-editor组件不兼容IE10及以下浏览器,请使用更高版本的浏览器查看', '浏览器不兼容通知', { |
|||
confirmButtonText: '确定' |
|||
}); |
|||
} else { |
|||
next(); |
|||
} |
|||
} |
|||
}); |
|||
|
|||
new Vue({ |
|||
router, |
|||
i18n, |
|||
render: h => h(App) |
|||
}).$mount('#app'); |
|||
@ -0,0 +1,117 @@ |
|||
import Vue from 'vue'; |
|||
import Router from 'vue-router'; |
|||
|
|||
Vue.use(Router); |
|||
|
|||
export default new Router({ |
|||
routes: [ |
|||
{ |
|||
path: '/', |
|||
redirect: '/dashboard' |
|||
}, |
|||
{ |
|||
path: '/', |
|||
component: () => import(/* webpackChunkName: "home" */ '../components/common/Home.vue'), |
|||
meta: { title: '自述文件' }, |
|||
children: [ |
|||
{ |
|||
path: '/dashboard', |
|||
component: () => import(/* webpackChunkName: "dashboard" */ '../components/page/Dashboard.vue'), |
|||
meta: { title: '系统首页' } |
|||
}, |
|||
{ |
|||
path: '/icon', |
|||
component: () => import(/* webpackChunkName: "icon" */ '../components/page/Icon.vue'), |
|||
meta: { title: '自定义图标' } |
|||
}, |
|||
{ |
|||
path: '/table', |
|||
component: () => import(/* webpackChunkName: "table" */ '../components/page/BaseTable.vue'), |
|||
meta: { title: '基础表格' } |
|||
}, |
|||
{ |
|||
path: '/tabs', |
|||
component: () => import(/* webpackChunkName: "tabs" */ '../components/page/Tabs.vue'), |
|||
meta: { title: 'tab选项卡' } |
|||
}, |
|||
{ |
|||
path: '/form', |
|||
component: () => import(/* webpackChunkName: "form" */ '../components/page/BaseForm.vue'), |
|||
meta: { title: '基本表单' } |
|||
}, |
|||
{ |
|||
// 富文本编辑器组件
|
|||
path: '/editor', |
|||
component: () => import(/* webpackChunkName: "editor" */ '../components/page/VueEditor.vue'), |
|||
meta: { title: '富文本编辑器' } |
|||
}, |
|||
{ |
|||
// markdown组件
|
|||
path: '/markdown', |
|||
component: () => import(/* webpackChunkName: "markdown" */ '../components/page/Markdown.vue'), |
|||
meta: { title: 'markdown编辑器' } |
|||
}, |
|||
{ |
|||
// 图片上传组件
|
|||
path: '/upload', |
|||
component: () => import(/* webpackChunkName: "upload" */ '../components/page/Upload.vue'), |
|||
meta: { title: '文件上传' } |
|||
}, |
|||
{ |
|||
// vue-schart组件
|
|||
path: '/charts', |
|||
component: () => import(/* webpackChunkName: "chart" */ '../components/page/BaseCharts.vue'), |
|||
meta: { title: 'schart图表' } |
|||
}, |
|||
{ |
|||
// 拖拽列表组件
|
|||
path: '/drag', |
|||
component: () => import(/* webpackChunkName: "drag" */ '../components/page/DragList.vue'), |
|||
meta: { title: '拖拽列表' } |
|||
}, |
|||
{ |
|||
// 拖拽Dialog组件
|
|||
path: '/dialog', |
|||
component: () => import(/* webpackChunkName: "dragdialog" */ '../components/page/DragDialog.vue'), |
|||
meta: { title: '拖拽弹框' } |
|||
}, |
|||
{ |
|||
// 国际化组件
|
|||
path: '/i18n', |
|||
component: () => import(/* webpackChunkName: "i18n" */ '../components/page/I18n.vue'), |
|||
meta: { title: '国际化' } |
|||
}, |
|||
{ |
|||
// 权限页面
|
|||
path: '/permission', |
|||
component: () => import(/* webpackChunkName: "permission" */ '../components/page/Permission.vue'), |
|||
meta: { title: '权限测试', permission: true } |
|||
}, |
|||
{ |
|||
path: '/404', |
|||
component: () => import(/* webpackChunkName: "404" */ '../components/page/404.vue'), |
|||
meta: { title: '404' } |
|||
}, |
|||
{ |
|||
path: '/403', |
|||
component: () => import(/* webpackChunkName: "403" */ '../components/page/403.vue'), |
|||
meta: { title: '403' } |
|||
}, |
|||
{ |
|||
path: '/donate', |
|||
component: () => import(/* webpackChunkName: "donate" */ '../components/page/Donate.vue'), |
|||
meta: { title: '支持作者' } |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
path: '/login', |
|||
component: () => import(/* webpackChunkName: "login" */ '../components/page/Login.vue'), |
|||
meta: { title: '登录' } |
|||
}, |
|||
{ |
|||
path: '*', |
|||
redirect: '/404' |
|||
} |
|||
] |
|||
}); |
|||
@ -0,0 +1,34 @@ |
|||
import axios from 'axios'; |
|||
|
|||
const service = axios.create({ |
|||
// process.env.NODE_ENV === 'development' 来判断是否开发环境
|
|||
// easy-mock服务挂了,暂时不使用了
|
|||
// baseURL: 'https://www.easy-mock.com/mock/592501a391470c0ac1fab128',
|
|||
timeout: 5000 |
|||
}); |
|||
|
|||
service.interceptors.request.use( |
|||
config => { |
|||
return config; |
|||
}, |
|||
error => { |
|||
console.log(error); |
|||
return Promise.reject(); |
|||
} |
|||
); |
|||
|
|||
service.interceptors.response.use( |
|||
response => { |
|||
if (response.status === 200) { |
|||
return response.data; |
|||
} else { |
|||
Promise.reject(); |
|||
} |
|||
}, |
|||
error => { |
|||
console.log(error); |
|||
return Promise.reject(); |
|||
} |
|||
); |
|||
|
|||
export default service; |
|||
@ -0,0 +1,16 @@ |
|||
module.exports = { |
|||
baseUrl: './', |
|||
assetsDir: 'static', |
|||
productionSourceMap: false, |
|||
// devServer: {
|
|||
// proxy: {
|
|||
// '/api':{
|
|||
// target:'http://jsonplaceholder.typicode.com',
|
|||
// changeOrigin:true,
|
|||
// pathRewrite:{
|
|||
// '/api':''
|
|||
// }
|
|||
// }
|
|||
// }
|
|||
// }
|
|||
} |
|||
Loading…
Reference in new issue