Compare commits
36 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
9b5f0160af | ||
|
0e4ea0871c | ||
|
88429bd809 | ||
|
62a9565f86 | ||
|
f663b23b29 | ||
|
afd255d5ba | ||
|
b7c8079350 | ||
|
543a9928cf | ||
|
8f37950589 | ||
|
6821eac35b | ||
|
cc5e62d5f5 | ||
|
0cccc636b8 | ||
|
563ce873bd | ||
|
44e94b2d16 | ||
|
a160848367 | ||
|
7099e6a3eb | ||
|
14fee27a92 | ||
|
7003a79ef6 | ||
|
c5faa63ee5 | ||
|
d29a9486a2 | ||
|
01442ce4d7 | ||
|
f28a7149fb | ||
|
51ad902d8f | ||
|
3cff6dcf4c | ||
|
afe975b3c2 | ||
|
d0eebf83c4 | ||
|
a55b149b27 | ||
|
fc19121311 | ||
|
de06619266 | ||
|
88c28f5d7e | ||
|
26b84847dd | ||
|
3cc3e134c2 | ||
|
2afb1dfabb | ||
|
5fe3d70246 | ||
|
4aa9345d90 | ||
|
0fcbf4b53b |
@@ -7,7 +7,7 @@
|
|||||||
<img src="https://img.shields.io/badge/vue-2.5.10-brightgreen.svg" alt="vue">
|
<img src="https://img.shields.io/badge/vue-2.5.10-brightgreen.svg" alt="vue">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://github.com/ElemeFE/element">
|
<a href="https://github.com/ElemeFE/element">
|
||||||
<img src="https://img.shields.io/badge/element--ui-2.0.8-brightgreen.svg" alt="element-ui">
|
<img src="https://img.shields.io/badge/element--ui-2.3.0-brightgreen.svg" alt="element-ui">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://travis-ci.org/PanJiaChen/vue-element-admin" rel="nofollow">
|
<a href="https://travis-ci.org/PanJiaChen/vue-element-admin" rel="nofollow">
|
||||||
<img src="https://travis-ci.org/PanJiaChen/vue-element-admin.svg?branch=master" alt="Build Status">
|
<img src="https://travis-ci.org/PanJiaChen/vue-element-admin.svg?branch=master" alt="Build Status">
|
||||||
@@ -30,6 +30,8 @@ English | [简体中文](./README.zh-CN.md)
|
|||||||
|
|
||||||
- [Documentation](https://panjiachen.github.io/vue-element-admin-site/#/)
|
- [Documentation](https://panjiachen.github.io/vue-element-admin-site/#/)
|
||||||
|
|
||||||
|
- [Gitter](https://gitter.im/vue-element-admin/discuss)
|
||||||
|
|
||||||
- [Wiki](https://github.com/PanJiaChen/vue-element-admin/wiki)
|
- [Wiki](https://github.com/PanJiaChen/vue-element-admin/wiki)
|
||||||
|
|
||||||
- [Donate](https://panjiachen.github.io/vue-element-admin-site/#/donate)
|
- [Donate](https://panjiachen.github.io/vue-element-admin-site/#/donate)
|
||||||
@@ -39,7 +41,7 @@ English | [简体中文](./README.zh-CN.md)
|
|||||||
- Base template recommends using: [vueAdmin-template](https://github.com/PanJiaChen/vueAdmin-template)
|
- Base template recommends using: [vueAdmin-template](https://github.com/PanJiaChen/vueAdmin-template)
|
||||||
- Desktop: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
|
- Desktop: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
|
||||||
|
|
||||||
**Note: This project uses element-ui@2.0.0+ version, so the minimum compatible vue@2.5.0+**
|
**Note: This project uses element-ui@2.3.0+ version, so the minimum compatible vue@2.5.0+**
|
||||||
|
|
||||||
## Preparation
|
## Preparation
|
||||||
|
|
||||||
@@ -86,6 +88,7 @@ You need to install [node](http://nodejs.org/) and [git](https://git-scm.com/) l
|
|||||||
- Form example
|
- Form example
|
||||||
- Two-step login
|
- Two-step login
|
||||||
- SplitPane
|
- SplitPane
|
||||||
|
- Drag Dialog
|
||||||
- Dropzone
|
- Dropzone
|
||||||
- Sticky
|
- Sticky
|
||||||
- CountTo
|
- CountTo
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<img src="https://img.shields.io/badge/vue-2.5.10-brightgreen.svg" alt="vue">
|
<img src="https://img.shields.io/badge/vue-2.5.10-brightgreen.svg" alt="vue">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://github.com/ElemeFE/element">
|
<a href="https://github.com/ElemeFE/element">
|
||||||
<img src="https://img.shields.io/badge/element--ui-2.0.8-brightgreen.svg" alt="element-ui">
|
<img src="https://img.shields.io/badge/element--ui-2.3.0-brightgreen.svg" alt="element-ui">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://travis-ci.org/PanJiaChen/vue-element-admin" rel="nofollow">
|
<a href="https://travis-ci.org/PanJiaChen/vue-element-admin" rel="nofollow">
|
||||||
<img src="https://travis-ci.org/PanJiaChen/vue-element-admin.svg?branch=master" alt="Build Status">
|
<img src="https://travis-ci.org/PanJiaChen/vue-element-admin.svg?branch=master" alt="Build Status">
|
||||||
@@ -30,6 +30,8 @@
|
|||||||
|
|
||||||
- [使用文档](https://panjiachen.github.io/vue-element-admin-site/#/zh-cn/)
|
- [使用文档](https://panjiachen.github.io/vue-element-admin-site/#/zh-cn/)
|
||||||
|
|
||||||
|
- [Gitter讨论组](https://gitter.im/vue-element-admin/discuss)
|
||||||
|
|
||||||
- [Wiki](https://github.com/PanJiaChen/vue-element-admin/wiki)
|
- [Wiki](https://github.com/PanJiaChen/vue-element-admin/wiki)
|
||||||
|
|
||||||
- [Donate](https://panjiachen.github.io/vue-element-admin-site/#/zh-cn/donate)
|
- [Donate](https://panjiachen.github.io/vue-element-admin-site/#/zh-cn/donate)
|
||||||
@@ -38,7 +40,7 @@
|
|||||||
- 模板建议使用: [vueAdmin-template](https://github.com/PanJiaChen/vueAdmin-template)
|
- 模板建议使用: [vueAdmin-template](https://github.com/PanJiaChen/vueAdmin-template)
|
||||||
- 桌面端: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
|
- 桌面端: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
|
||||||
|
|
||||||
**注意:该项目使用 element-ui@2.0.0+ 版本,所以最低兼容 vue@2.5.0+**
|
**注意:该项目使用 element-ui@2.3.0+ 版本,所以最低兼容 vue@2.5.0+**
|
||||||
|
|
||||||
## 前序准备
|
## 前序准备
|
||||||
|
|
||||||
@@ -52,7 +54,6 @@
|
|||||||
- [手摸手,带你封装一个 vue component](https://segmentfault.com/a/1190000009090836)
|
- [手摸手,带你封装一个 vue component](https://segmentfault.com/a/1190000009090836)
|
||||||
- [手摸手,带你优雅的使用 icon](https://juejin.im/post/59bb864b5188257e7a427c09)
|
- [手摸手,带你优雅的使用 icon](https://juejin.im/post/59bb864b5188257e7a427c09)
|
||||||
|
|
||||||
响应需求,开了一个qq群 `591724180` 方便大家交流
|
|
||||||
|
|
||||||
或者加入该群主 **[圈子](https://jianshiapp.com/circles/1209)** 楼主会经常分享一些技术相关的东西
|
或者加入该群主 **[圈子](https://jianshiapp.com/circles/1209)** 楼主会经常分享一些技术相关的东西
|
||||||
|
|
||||||
@@ -99,6 +100,7 @@
|
|||||||
- Form example
|
- Form example
|
||||||
- 二步登录
|
- 二步登录
|
||||||
- SplitPane
|
- SplitPane
|
||||||
|
- 拖拽 Dialog
|
||||||
- Dropzone
|
- Dropzone
|
||||||
- Sticky
|
- Sticky
|
||||||
- CountTo
|
- CountTo
|
||||||
|
@@ -7,8 +7,8 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||||
<title>vue-element-admin</title>
|
<title>vue-element-admin</title>
|
||||||
</head>
|
</head>
|
||||||
<script src=<%= htmlWebpackPlugin.options.path %>/tinymce4.7.5/tinymce.min.js></script>
|
|
||||||
<body>
|
<body>
|
||||||
|
<script src=<%= htmlWebpackPlugin.options.path %>/tinymce4.7.5/tinymce.min.js></script>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
<!-- built files will be auto injected -->
|
<!-- built files will be auto injected -->
|
||||||
</body>
|
</body>
|
||||||
|
21
package.json
21
package.json
@@ -1,10 +1,9 @@
|
|||||||
{
|
{
|
||||||
"name": "vue-element-admin",
|
"name": "vue-element-admin",
|
||||||
"version": "3.6.3",
|
"version": "3.6.6",
|
||||||
"description": "A magical vue admin. Typical templates for enterprise applications. Newest development stack of vue. Lots of awesome features",
|
"description": "A magical vue admin. Typical templates for enterprise applications. Newest development stack of vue. Lots of awesome features",
|
||||||
"author": "Pan <panfree23@gmail.com>",
|
"author": "Pan <panfree23@gmail.com>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"private": true,
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
|
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
|
||||||
"build:prod": "cross-env NODE_ENV=production env_config=prod node build/build.js",
|
"build:prod": "cross-env NODE_ENV=production env_config=prod node build/build.js",
|
||||||
@@ -12,13 +11,27 @@
|
|||||||
"lint": "eslint --ext .js,.vue src",
|
"lint": "eslint --ext .js,.vue src",
|
||||||
"test": "npm run lint"
|
"test": "npm run lint"
|
||||||
},
|
},
|
||||||
|
"keywords": [
|
||||||
|
"vue",
|
||||||
|
"element-ui",
|
||||||
|
"admin",
|
||||||
|
"management-system",
|
||||||
|
"admin-template"
|
||||||
|
],
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/PanJiaChen/vue-element-admin.git"
|
||||||
|
},
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/PanJiaChen/vue-element-admin/issues"
|
||||||
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "0.17.1",
|
"axios": "0.17.1",
|
||||||
"clipboard": "1.7.1",
|
"clipboard": "1.7.1",
|
||||||
"codemirror": "5.32.0",
|
"codemirror": "5.32.0",
|
||||||
"dropzone": "5.2.0",
|
"dropzone": "5.2.0",
|
||||||
"echarts": "3.8.5",
|
"echarts": "3.8.5",
|
||||||
"element-ui": "2.0.8",
|
"element-ui": "2.3.2",
|
||||||
"file-saver": "1.3.3",
|
"file-saver": "1.3.3",
|
||||||
"font-awesome": "4.7.0",
|
"font-awesome": "4.7.0",
|
||||||
"js-cookie": "2.2.0",
|
"js-cookie": "2.2.0",
|
||||||
@@ -37,7 +50,7 @@
|
|||||||
"vue-multiselect": "2.0.8",
|
"vue-multiselect": "2.0.8",
|
||||||
"vue-router": "3.0.1",
|
"vue-router": "3.0.1",
|
||||||
"vue-splitpane": "1.0.2",
|
"vue-splitpane": "1.0.2",
|
||||||
"vuedraggable": "2.15.0",
|
"vuedraggable": "^2.16.0",
|
||||||
"vuex": "3.0.1",
|
"vuex": "3.0.1",
|
||||||
"xlsx": "^0.11.16"
|
"xlsx": "^0.11.16"
|
||||||
},
|
},
|
||||||
|
@@ -25,7 +25,8 @@ export default {
|
|||||||
},
|
},
|
||||||
customStyle: {
|
customStyle: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: {
|
default: function() {
|
||||||
|
return {
|
||||||
right: '50px',
|
right: '50px',
|
||||||
bottom: '50px',
|
bottom: '50px',
|
||||||
width: '40px',
|
width: '40px',
|
||||||
@@ -34,6 +35,7 @@ export default {
|
|||||||
'line-height': '45px',
|
'line-height': '45px',
|
||||||
background: '#e7eaf1'
|
background: '#e7eaf1'
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
transitionName: {
|
transitionName: {
|
||||||
type: String,
|
type: String,
|
||||||
|
@@ -395,6 +395,7 @@ export default {
|
|||||||
off() {
|
off() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.$emit('input', false)
|
this.$emit('input', false)
|
||||||
|
this.$emit('close')
|
||||||
if (this.step == 3 && this.loading == 2) {
|
if (this.step == 3 && this.loading == 2) {
|
||||||
this.setStep(1)
|
this.setStep(1)
|
||||||
}
|
}
|
||||||
|
89
src/components/Kanban/index.vue
Normal file
89
src/components/Kanban/index.vue
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
<template>
|
||||||
|
<div class="board-column">
|
||||||
|
<div class="board-column-header">
|
||||||
|
{{headerText}}
|
||||||
|
</div>
|
||||||
|
<draggable
|
||||||
|
class="board-column-content"
|
||||||
|
:list="list"
|
||||||
|
:options="options">
|
||||||
|
<div class="board-item" v-for="element in list" :key="element.id">
|
||||||
|
{{element.name}} {{element.id}}
|
||||||
|
</div>
|
||||||
|
</draggable>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import draggable from 'vuedraggable'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'dragKanban-demo',
|
||||||
|
components: {
|
||||||
|
draggable
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
headerText: {
|
||||||
|
type: String,
|
||||||
|
default: 'Header'
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
list: {
|
||||||
|
type: Array,
|
||||||
|
default() {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
.board-column {
|
||||||
|
min-width: 300px;
|
||||||
|
min-height: 100px;
|
||||||
|
height: auto;
|
||||||
|
overflow: hidden;
|
||||||
|
background: #f0f0f0;
|
||||||
|
border-radius: 3px;
|
||||||
|
|
||||||
|
.board-column-header {
|
||||||
|
height: 50px;
|
||||||
|
line-height: 50px;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0 20px;
|
||||||
|
text-align: center;
|
||||||
|
background: #333;
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 3px 3px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.board-column-content {
|
||||||
|
height: auto;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 10px solid transparent;
|
||||||
|
min-height: 60px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.board-item {
|
||||||
|
cursor: pointer;
|
||||||
|
width: 100%;
|
||||||
|
height: 64px;
|
||||||
|
margin: 5px 0;
|
||||||
|
background-color: #fff;
|
||||||
|
text-align: left;
|
||||||
|
line-height: 54px;
|
||||||
|
padding: 5px 10px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
box-shadow: 0px 1px 3px 0 rgba(0,0,0,0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@@ -19,7 +19,7 @@ export default {
|
|||||||
},
|
},
|
||||||
zIndex: {
|
zIndex: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 100
|
default: 1
|
||||||
},
|
},
|
||||||
width: {
|
width: {
|
||||||
type: String,
|
type: String,
|
||||||
|
@@ -153,7 +153,10 @@ export default {
|
|||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.tinymce-container {
|
.tinymce-container {
|
||||||
position: relative
|
position: relative;
|
||||||
|
}
|
||||||
|
.tinymce-container>>>.mce-fullscreen {
|
||||||
|
z-index: 10000;
|
||||||
}
|
}
|
||||||
.tinymce-textarea {
|
.tinymce-textarea {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
|
@@ -2,6 +2,6 @@
|
|||||||
// Detail plugins list see https://www.tinymce.com/docs/plugins/
|
// Detail plugins list see https://www.tinymce.com/docs/plugins/
|
||||||
// Custom builds see https://www.tinymce.com/download/custom-builds/
|
// Custom builds see https://www.tinymce.com/download/custom-builds/
|
||||||
|
|
||||||
const plugins = ['advlist anchor autolink autoresize autosave bbcode code codesample colorpicker colorpicker contextmenu directionality emoticons fullpage fullscreen hr image imagetools importcss insertdatetime legacyoutput link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor textpattern visualblocks visualchars wordcount']
|
const plugins = ['advlist anchor autolink autosave code codesample colorpicker colorpicker contextmenu directionality emoticons fullscreen hr image imagetools importcss insertdatetime legacyoutput link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor textpattern visualblocks visualchars wordcount']
|
||||||
|
|
||||||
export default plugins
|
export default plugins
|
||||||
|
@@ -28,7 +28,7 @@
|
|||||||
import { getToken } from '@/api/qiniu'
|
import { getToken } from '@/api/qiniu'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'singleImageUpload',
|
name: 'singleImageUpload3',
|
||||||
props: {
|
props: {
|
||||||
value: String
|
value: String
|
||||||
},
|
},
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<input id="excel-upload-input" type="file" accept=".xlsx, .xls" class="c-hide" @change="handkeFileChange">
|
<input id="excel-upload-input" ref="excel-upload-input" type="file" accept=".xlsx, .xls" class="c-hide" @change="handkeFileChange">
|
||||||
<div id="drop" @drop="handleDrop" @dragover="handleDragover" @dragenter="handleDragover">
|
<div id="drop" @drop="handleDrop" @dragover="handleDragover" @dragenter="handleDragover">
|
||||||
Drop excel file here or
|
Drop excel file here or
|
||||||
<el-button style="margin-left:16px;" size="mini" type="primary" @click="handleUpload">browse</el-button>
|
<el-button style="margin-left:16px;" size="mini" type="primary" @click="handleUpload">browse</el-button>
|
||||||
@@ -51,7 +51,9 @@ export default {
|
|||||||
handkeFileChange(e) {
|
handkeFileChange(e) {
|
||||||
const files = e.target.files
|
const files = e.target.files
|
||||||
const itemFile = files[0] // only use files[0]
|
const itemFile = files[0] // only use files[0]
|
||||||
|
if (!itemFile) return
|
||||||
this.readerData(itemFile)
|
this.readerData(itemFile)
|
||||||
|
this.$refs['excel-upload-input'].value = null // fix can't select the same excel
|
||||||
},
|
},
|
||||||
readerData(itemFile) {
|
readerData(itemFile) {
|
||||||
const reader = new FileReader()
|
const reader = new FileReader()
|
||||||
|
74
src/directive/el-dragDialog/drag.js
Normal file
74
src/directive/el-dragDialog/drag.js
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
export default{
|
||||||
|
bind(el, binding) {
|
||||||
|
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);
|
||||||
|
function getStyle(dom, attr) {
|
||||||
|
if (dom.currentStyle) {
|
||||||
|
return dom.currentStyle[attr]
|
||||||
|
} else {
|
||||||
|
return getComputedStyle(dom, false)[attr]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogHeaderEl.onmousedown = (e) => {
|
||||||
|
// 鼠标按下,计算当前元素距离可视区的距离
|
||||||
|
const disX = e.clientX - dialogHeaderEl.offsetLeft
|
||||||
|
const disY = e.clientY - dialogHeaderEl.offsetTop
|
||||||
|
|
||||||
|
const dragDomWidth = dragDom.offsetWidth
|
||||||
|
const dragDomheight = dragDom.offsetHeight
|
||||||
|
|
||||||
|
const screenWidth = document.body.clientWidth
|
||||||
|
const screenHeight = document.body.clientHeight
|
||||||
|
|
||||||
|
const minDragDomLeft = dragDom.offsetLeft
|
||||||
|
const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth
|
||||||
|
|
||||||
|
const minDragDomTop = dragDom.offsetTop
|
||||||
|
const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomheight
|
||||||
|
|
||||||
|
// 获取到的值带px 正则匹配替换
|
||||||
|
let styL = getStyle(dragDom, 'left')
|
||||||
|
let styT = getStyle(dragDom, 'top')
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
src/directive/el-dragDialog/index.js
Normal file
13
src/directive/el-dragDialog/index.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import drag from './drag'
|
||||||
|
|
||||||
|
const install = function(Vue) {
|
||||||
|
Vue.directive('el-drag-dialog', drag)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window.Vue) {
|
||||||
|
window['el-drag-dialog'] = drag
|
||||||
|
Vue.use(install); // eslint-disable-line
|
||||||
|
}
|
||||||
|
|
||||||
|
drag.install = install
|
||||||
|
export default drag
|
@@ -18,6 +18,8 @@ export default {
|
|||||||
countTo: 'CountTo',
|
countTo: 'CountTo',
|
||||||
componentMixin: 'Mixin',
|
componentMixin: 'Mixin',
|
||||||
backToTop: 'BackToTop',
|
backToTop: 'BackToTop',
|
||||||
|
dragDialog: 'Drag Dialog',
|
||||||
|
dragKanban: 'Drag Kanban',
|
||||||
charts: 'Charts',
|
charts: 'Charts',
|
||||||
keyboardChart: 'Keyboard Chart',
|
keyboardChart: 'Keyboard Chart',
|
||||||
lineChart: 'Line Chart',
|
lineChart: 'Line Chart',
|
||||||
|
@@ -18,6 +18,8 @@ export default {
|
|||||||
countTo: 'CountTo',
|
countTo: 'CountTo',
|
||||||
componentMixin: '小组件',
|
componentMixin: '小组件',
|
||||||
backToTop: '返回顶部',
|
backToTop: '返回顶部',
|
||||||
|
dragDialog: '拖拽 Dialog',
|
||||||
|
dragKanban: '可拖拽看板',
|
||||||
charts: '图表',
|
charts: '图表',
|
||||||
keyboardChart: '键盘图表',
|
keyboardChart: '键盘图表',
|
||||||
lineChart: '折线图',
|
lineChart: '折线图',
|
||||||
|
@@ -111,7 +111,9 @@ export const asyncRouterMap = [
|
|||||||
{ path: 'sticky', component: _import('components-demo/sticky'), name: 'sticky-demo', meta: { title: 'sticky' }},
|
{ path: 'sticky', component: _import('components-demo/sticky'), name: 'sticky-demo', meta: { title: 'sticky' }},
|
||||||
{ path: 'count-to', component: _import('components-demo/countTo'), name: 'countTo-demo', meta: { title: 'countTo' }},
|
{ path: 'count-to', component: _import('components-demo/countTo'), name: 'countTo-demo', meta: { title: 'countTo' }},
|
||||||
{ path: 'mixin', component: _import('components-demo/mixin'), name: 'componentMixin-demo', meta: { title: 'componentMixin' }},
|
{ path: 'mixin', component: _import('components-demo/mixin'), name: 'componentMixin-demo', meta: { title: 'componentMixin' }},
|
||||||
{ path: 'back-to-top', component: _import('components-demo/backToTop'), name: 'backToTop-demo', meta: { title: 'backToTop' }}
|
{ path: 'back-to-top', component: _import('components-demo/backToTop'), name: 'backToTop-demo', meta: { title: 'backToTop' }},
|
||||||
|
{ path: 'drag-dialog', component: _import('components-demo/dragDialog'), name: 'dragDialog-demo', meta: { title: 'dragDialog' }},
|
||||||
|
{ path: 'drag-kanban', component: _import('components-demo/dragKanban'), name: 'dragKanban-demo', meta: { title: 'dragKanban' }}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
const getters = {
|
const getters = {
|
||||||
sidebar: state => state.app.sidebar,
|
sidebar: state => state.app.sidebar,
|
||||||
language: state => state.app.language,
|
language: state => state.app.language,
|
||||||
|
device: state => state.app.device,
|
||||||
visitedViews: state => state.tagsView.visitedViews,
|
visitedViews: state => state.tagsView.visitedViews,
|
||||||
cachedViews: state => state.tagsView.cachedViews,
|
cachedViews: state => state.tagsView.cachedViews,
|
||||||
token: state => state.user.token,
|
token: state => state.user.token,
|
||||||
|
@@ -3,8 +3,10 @@ import Cookies from 'js-cookie'
|
|||||||
const app = {
|
const app = {
|
||||||
state: {
|
state: {
|
||||||
sidebar: {
|
sidebar: {
|
||||||
opened: !+Cookies.get('sidebarStatus')
|
opened: !+Cookies.get('sidebarStatus'),
|
||||||
|
withoutAnimation: false
|
||||||
},
|
},
|
||||||
|
device: 'desktop',
|
||||||
language: Cookies.get('language') || 'en'
|
language: Cookies.get('language') || 'en'
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
@@ -15,6 +17,15 @@ const app = {
|
|||||||
Cookies.set('sidebarStatus', 0)
|
Cookies.set('sidebarStatus', 0)
|
||||||
}
|
}
|
||||||
state.sidebar.opened = !state.sidebar.opened
|
state.sidebar.opened = !state.sidebar.opened
|
||||||
|
state.sidebar.withoutAnimation = false
|
||||||
|
},
|
||||||
|
CLOSE_SIDEBAR: (state, withoutAnimation) => {
|
||||||
|
Cookies.set('sidebarStatus', 1)
|
||||||
|
state.sidebar.opened = false
|
||||||
|
state.sidebar.withoutAnimation = withoutAnimation
|
||||||
|
},
|
||||||
|
TOGGLE_DEVICE: (state, device) => {
|
||||||
|
state.device = device
|
||||||
},
|
},
|
||||||
SET_LANGUAGE: (state, language) => {
|
SET_LANGUAGE: (state, language) => {
|
||||||
state.language = language
|
state.language = language
|
||||||
@@ -25,6 +36,12 @@ const app = {
|
|||||||
toggleSideBar({ commit }) {
|
toggleSideBar({ commit }) {
|
||||||
commit('TOGGLE_SIDEBAR')
|
commit('TOGGLE_SIDEBAR')
|
||||||
},
|
},
|
||||||
|
closeSideBar({ commit }, { withoutAnimation }) {
|
||||||
|
commit('CLOSE_SIDEBAR', withoutAnimation)
|
||||||
|
},
|
||||||
|
toggleDevice({ commit }, device) {
|
||||||
|
commit('TOGGLE_DEVICE', device)
|
||||||
|
},
|
||||||
setLanguage({ commit }, language) {
|
setLanguage({ commit }, language) {
|
||||||
commit('SET_LANGUAGE', language)
|
commit('SET_LANGUAGE', language)
|
||||||
}
|
}
|
||||||
|
@@ -73,3 +73,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//dropdown
|
||||||
|
.el-dropdown-menu{
|
||||||
|
a{
|
||||||
|
display: block
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1,19 +1,27 @@
|
|||||||
#app {
|
#app {
|
||||||
|
|
||||||
// 主体区域
|
// 主体区域
|
||||||
.main-container {
|
.main-container {
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
transition: margin-left 0.28s;
|
transition: margin-left .28s;
|
||||||
margin-left: 180px;
|
margin-left: 180px;
|
||||||
} // 侧边栏
|
}
|
||||||
|
|
||||||
|
// 侧边栏
|
||||||
.sidebar-container {
|
.sidebar-container {
|
||||||
transition: width 0.28s;
|
.horizontal-collapse-transition {
|
||||||
width: 180px!important;
|
transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out;
|
||||||
|
}
|
||||||
|
transition: width .28s;
|
||||||
|
width: 180px !important;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
font-size: 0px;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
z-index: 1001;
|
z-index: 1001;
|
||||||
|
overflow: hidden;
|
||||||
a {
|
a {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -23,78 +31,75 @@
|
|||||||
}
|
}
|
||||||
.el-menu {
|
.el-menu {
|
||||||
border: none;
|
border: none;
|
||||||
width: 100%;
|
width: 100% !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.hideSidebar {
|
.hideSidebar {
|
||||||
.sidebar-container,.sidebar-container .el-menu {
|
.sidebar-container {
|
||||||
width: 36px!important;
|
width: 36px !important;
|
||||||
// overflow: inherit;
|
|
||||||
}
|
}
|
||||||
.main-container {
|
.main-container {
|
||||||
margin-left: 36px;
|
margin-left: 36px;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
.hideSidebar {
|
|
||||||
.submenu-title-noDropdown {
|
.submenu-title-noDropdown {
|
||||||
padding-left: 10px!important;
|
padding-left: 10px !important;
|
||||||
position: relative;
|
position: relative;
|
||||||
span {
|
.el-tooltip {
|
||||||
height: 0;
|
padding: 0 10px !important;
|
||||||
width: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
visibility: hidden;
|
|
||||||
transition: opacity .3s cubic-bezier(.55, 0, .1, 1);
|
|
||||||
opacity: 0;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
&:hover {
|
|
||||||
span {
|
|
||||||
display: block;
|
|
||||||
border-radius: 3px;
|
|
||||||
z-index: 1002;
|
|
||||||
width: 140px;
|
|
||||||
height: 56px;
|
|
||||||
visibility: visible;
|
|
||||||
position: absolute;
|
|
||||||
right: -145px;
|
|
||||||
text-align: left;
|
|
||||||
text-indent: 20px;
|
|
||||||
top: 0px;
|
|
||||||
background-color: $subMenuBg!important;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.el-submenu {
|
.el-submenu {
|
||||||
&>.el-submenu__title {
|
&>.el-submenu__title {
|
||||||
padding-left: 10px!important;
|
padding-left: 10px !important;
|
||||||
&>span {
|
&>span {
|
||||||
display: none;
|
height: 0;
|
||||||
|
width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
visibility: hidden;
|
||||||
|
display: inline-block;
|
||||||
}
|
}
|
||||||
.el-submenu__icon-arrow {
|
.el-submenu__icon-arrow {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.nest-menu {
|
|
||||||
.el-submenu__icon-arrow {
|
|
||||||
display: block!important;
|
|
||||||
}
|
|
||||||
span {
|
|
||||||
display: inline-block!important;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
.sidebar-container .nest-menu .el-submenu>.el-submenu__title,
|
||||||
.nest-menu .el-submenu>.el-submenu__title,
|
.sidebar-container .el-submenu .el-menu-item {
|
||||||
.el-submenu .el-menu-item {
|
min-width: 180px !important;
|
||||||
min-width: 180px!important;
|
background-color: $subMenuBg !important;
|
||||||
background-color: $subMenuBg!important;
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: $menuHover!important;
|
background-color: $menuHover !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.el-menu--collapse .el-menu .el-submenu{
|
.el-menu--collapse .el-menu .el-submenu {
|
||||||
min-width: 180px!important;
|
min-width: 180px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
//适配移动端
|
||||||
|
.mobile {
|
||||||
|
.main-container {
|
||||||
|
margin-left: 0px;
|
||||||
|
}
|
||||||
|
.sidebar-container {
|
||||||
|
top: 50px;
|
||||||
|
transition: transform .28s;
|
||||||
|
width: 180px !important;
|
||||||
|
}
|
||||||
|
&.hideSidebar {
|
||||||
|
.sidebar-container {
|
||||||
|
transition-duration: 0.3s;
|
||||||
|
transform: translate3d(-180px, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.withoutAnimation {
|
||||||
|
.main-container,
|
||||||
|
.sidebar-container {
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -131,16 +131,14 @@ export function objectMerge(target, source) {
|
|||||||
if (Array.isArray(source)) {
|
if (Array.isArray(source)) {
|
||||||
return source.slice()
|
return source.slice()
|
||||||
}
|
}
|
||||||
for (const property in source) {
|
Object.keys(source).forEach((property) => {
|
||||||
if (source.hasOwnProperty(property)) {
|
|
||||||
const sourceProperty = source[property]
|
const sourceProperty = source[property]
|
||||||
if (typeof sourceProperty === 'object') {
|
if (typeof sourceProperty === 'object') {
|
||||||
target[property] = objectMerge(target[property], sourceProperty)
|
target[property] = objectMerge(target[property], sourceProperty)
|
||||||
continue
|
} else {
|
||||||
}
|
|
||||||
target[property] = sourceProperty
|
target[property] = sourceProperty
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
return target
|
return target
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,15 +251,13 @@ export function deepClone(source) {
|
|||||||
throw new Error('error arguments', 'shallowClone')
|
throw new Error('error arguments', 'shallowClone')
|
||||||
}
|
}
|
||||||
const targetObj = source.constructor === Array ? [] : {}
|
const targetObj = source.constructor === Array ? [] : {}
|
||||||
for (const keys in source) {
|
Object.keys(source).forEach((keys) => {
|
||||||
if (source.hasOwnProperty(keys)) {
|
|
||||||
if (source[keys] && typeof source[keys] === 'object') {
|
if (source[keys] && typeof source[keys] === 'object') {
|
||||||
targetObj[keys] = source[keys].constructor === Array ? [] : {}
|
targetObj[keys] = source[keys].constructor === Array ? [] : {}
|
||||||
targetObj[keys] = deepClone(source[keys])
|
targetObj[keys] = deepClone(source[keys])
|
||||||
} else {
|
} else {
|
||||||
targetObj[keys] = source[keys]
|
targetObj[keys] = source[keys]
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
|
||||||
return targetObj
|
return targetObj
|
||||||
}
|
}
|
||||||
|
@@ -26,7 +26,7 @@ export function validateUpperCase(str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 大小写字母*/
|
/* 大小写字母*/
|
||||||
export function validatAlphabets(str) {
|
export function validateAlphabets(str) {
|
||||||
const reg = /^[A-Za-z]+$/
|
const reg = /^[A-Za-z]+$/
|
||||||
return reg.test(str)
|
return reg.test(str)
|
||||||
}
|
}
|
||||||
|
14
src/vendor/Export2Excel.js
vendored
14
src/vendor/Export2Excel.js
vendored
@@ -116,16 +116,14 @@ export function export_table_to_excel(id) {
|
|||||||
saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), "test.xlsx")
|
saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), "test.xlsx")
|
||||||
}
|
}
|
||||||
|
|
||||||
export function export_json_to_excel(th, jsonData, defaultTitle) {
|
export function export_json_to_excel({header, data, filename='excel-list', autoWidth=true}={}) {
|
||||||
|
|
||||||
/* original data */
|
/* original data */
|
||||||
|
data=[...data]
|
||||||
var data = jsonData;
|
data.unshift(header);
|
||||||
data.unshift(th);
|
|
||||||
var ws_name = "SheetJS";
|
var ws_name = "SheetJS";
|
||||||
|
|
||||||
var wb = new Workbook(), ws = sheet_from_array_of_arrays(data);
|
var wb = new Workbook(), ws = sheet_from_array_of_arrays(data);
|
||||||
|
|
||||||
|
if(autoWidth){
|
||||||
/*设置worksheet每列的最大宽度*/
|
/*设置worksheet每列的最大宽度*/
|
||||||
const colWidth = data.map(row => row.map(val => {
|
const colWidth = data.map(row => row.map(val => {
|
||||||
/*先判断是否为null/undefined*/
|
/*先判断是否为null/undefined*/
|
||||||
@@ -149,12 +147,12 @@ export function export_json_to_excel(th, jsonData, defaultTitle) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ws['!cols'] = result;
|
ws['!cols'] = result;
|
||||||
|
}
|
||||||
|
|
||||||
/* add worksheet to workbook */
|
/* add worksheet to workbook */
|
||||||
wb.SheetNames.push(ws_name);
|
wb.SheetNames.push(ws_name);
|
||||||
wb.Sheets[ws_name] = ws;
|
wb.Sheets[ws_name] = ws;
|
||||||
|
|
||||||
var wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: false, type: 'binary'});
|
var wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: false, type: 'binary'});
|
||||||
var title = defaultTitle || 'excel-list'
|
saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), filename + ".xlsx");
|
||||||
saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), title + ".xlsx")
|
|
||||||
}
|
}
|
||||||
|
43
src/views/components-demo/dragDialog.vue
Normal file
43
src/views/components-demo/dragDialog.vue
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<template>
|
||||||
|
<div class="components-container">
|
||||||
|
<el-button type="primary" @click="dialogTableVisible = true">open a Drag Dialog</el-button>
|
||||||
|
<el-dialog v-el-drag-dialog title="Shipping address" :visible.sync="dialogTableVisible">
|
||||||
|
<el-table :data="gridData">
|
||||||
|
<el-table-column property="date" label="Date" width="150"></el-table-column>
|
||||||
|
<el-table-column property="name" label="Name" width="200"></el-table-column>
|
||||||
|
<el-table-column property="address" label="Address"></el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import elDragDialog from '@/directive/el-dragDialog' // base on element-ui
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'dragDialog-demo',
|
||||||
|
directives: { elDragDialog },
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dialogTableVisible: false,
|
||||||
|
gridData: [{
|
||||||
|
date: '2016-05-02',
|
||||||
|
name: 'John Smith',
|
||||||
|
address: 'No.1518, Jinshajiang Road, Putuo District'
|
||||||
|
}, {
|
||||||
|
date: '2016-05-04',
|
||||||
|
name: 'John Smith',
|
||||||
|
address: 'No.1518, Jinshajiang Road, Putuo District'
|
||||||
|
}, {
|
||||||
|
date: '2016-05-01',
|
||||||
|
name: 'John Smith',
|
||||||
|
address: 'No.1518, Jinshajiang Road, Putuo District'
|
||||||
|
}, {
|
||||||
|
date: '2016-05-03',
|
||||||
|
name: 'John Smith',
|
||||||
|
address: 'No.1518, Jinshajiang Road, Putuo District'
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
68
src/views/components-demo/dragKanban.vue
Normal file
68
src/views/components-demo/dragKanban.vue
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<template>
|
||||||
|
<div class="components-container board">
|
||||||
|
<Kanban :key="1" class="kanban todo" :list="list1" :options="options" header-text="Todo"/>
|
||||||
|
<Kanban :key="2" class="kanban working" :list="list2" :options="options" header-text="Working"/>
|
||||||
|
<Kanban :key="3" class="kanban done" :list="list3" :options="options" header-text="Done"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import Kanban from '@/components/Kanban'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'dragKanban-demo',
|
||||||
|
components: {
|
||||||
|
Kanban
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
options: {
|
||||||
|
group: 'mission'
|
||||||
|
},
|
||||||
|
list1: [
|
||||||
|
{ name: 'Mission', id: 1 },
|
||||||
|
{ name: 'Mission', id: 2 },
|
||||||
|
{ name: 'Mission', id: 3 },
|
||||||
|
{ name: 'Mission', id: 4 }
|
||||||
|
],
|
||||||
|
list2: [
|
||||||
|
{ name: 'Mission', id: 5 },
|
||||||
|
{ name: 'Mission', id: 6 },
|
||||||
|
{ name: 'Mission', id: 7 }
|
||||||
|
],
|
||||||
|
list3: [
|
||||||
|
{ name: 'Mission', id: 8 },
|
||||||
|
{ name: 'Mission', id: 9 },
|
||||||
|
{ name: 'Mission', id: 10 }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
.board {
|
||||||
|
width: 1000px;
|
||||||
|
margin-left: 20px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
.kanban {
|
||||||
|
&.todo {
|
||||||
|
.board-column-header {
|
||||||
|
background: #4A9FF9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.working {
|
||||||
|
.board-column-header {
|
||||||
|
background: #f9944a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.done {
|
||||||
|
.board-column-header {
|
||||||
|
background: #2ac06d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@@ -231,7 +231,7 @@
|
|||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
height: 50px;
|
height: 40px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 0 8px 0 -3px #f6f6f6, 0 9px 1px -3px rgba(0, 0, 0, 0.2), 0 16px 0 -6px #f6f6f6, 0 17px 2px -6px rgba(0, 0, 0, 0.2);
|
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 0 8px 0 -3px #f6f6f6, 0 9px 1px -3px rgba(0, 0, 0, 0.2), 0 16px 0 -6px #f6f6f6, 0 17px 2px -6px rgba(0, 0, 0, 0.2);
|
||||||
}
|
}
|
||||||
@@ -245,6 +245,8 @@
|
|||||||
.filters {
|
.filters {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
}
|
}
|
||||||
.filters li {
|
.filters li {
|
||||||
|
@@ -49,8 +49,7 @@ export default {
|
|||||||
.dashboard-editor-container {
|
.dashboard-editor-container {
|
||||||
background-color: #e3e3e3;
|
background-color: #e3e3e3;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
margin-top: -50px;
|
padding: 50px 60px 0px;
|
||||||
padding: 100px 60px 0px;
|
|
||||||
.pan-info-roles {
|
.pan-info-roles {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
@@ -19,7 +19,7 @@ export default {
|
|||||||
{ title: '实战篇', href: 'https://segmentfault.com/a/1190000009762198' },
|
{ title: '实战篇', href: 'https://segmentfault.com/a/1190000009762198' },
|
||||||
{ title: 'vueAdmin-template 篇', href: 'https://segmentfault.com/a/1190000010043013' },
|
{ title: 'vueAdmin-template 篇', href: 'https://segmentfault.com/a/1190000010043013' },
|
||||||
{ title: '自行封装 component', href: 'https://segmentfault.com/a/1190000009090836' },
|
{ title: '自行封装 component', href: 'https://segmentfault.com/a/1190000009090836' },
|
||||||
{ title: '优雅的使用 icon', href: 'https://segmentfault.com/a/https://segmentfault.com/a/1190000012213278' }
|
{ title: '优雅的使用 icon', href: 'https://segmentfault.com/a/1190000012213278' }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -65,6 +65,7 @@ export default {
|
|||||||
.pan-img {
|
.pan-img {
|
||||||
display: block;
|
display: block;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
.text-jumbo {
|
.text-jumbo {
|
||||||
font-size: 60px;
|
font-size: 60px;
|
||||||
|
@@ -335,7 +335,11 @@ export default {
|
|||||||
const tHeader = ['timestamp', 'title', 'type', 'importance', 'status']
|
const tHeader = ['timestamp', 'title', 'type', 'importance', 'status']
|
||||||
const filterVal = ['timestamp', 'title', 'type', 'importance', 'status']
|
const filterVal = ['timestamp', 'title', 'type', 'importance', 'status']
|
||||||
const data = this.formatJson(filterVal, this.list)
|
const data = this.formatJson(filterVal, this.list)
|
||||||
excel.export_json_to_excel(tHeader, data, 'table-list')
|
excel.export_json_to_excel({
|
||||||
|
header: tHeader,
|
||||||
|
data,
|
||||||
|
filename: 'table-list'
|
||||||
|
})
|
||||||
this.downloadLoading = false
|
this.downloadLoading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@@ -1,8 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- $t is vue-i18n global function to translate lang -->
|
<!-- $t is vue-i18n global function to translate lang -->
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
|
|
||||||
|
<label class="radio-label" style="padding-left:0;">Filename: </label>
|
||||||
<el-input style='width:340px;' :placeholder="$t('excel.placeholder')" prefix-icon="el-icon-document" v-model="filename"></el-input>
|
<el-input style='width:340px;' :placeholder="$t('excel.placeholder')" prefix-icon="el-icon-document" v-model="filename"></el-input>
|
||||||
<el-button style='margin-bottom:20px;' type="primary" icon="document" @click="handleDownload" :loading="downloadLoading">{{$t('excel.export')}} excel</el-button>
|
<label class="radio-label">Cell Auto Width: </label>
|
||||||
|
<el-radio-group v-model="autoWidth">
|
||||||
|
<el-radio :label="true" border>True</el-radio>
|
||||||
|
<el-radio :label="false" border>False</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
<el-button style='margin:0 0 20px 20px;' type="primary" icon="document" @click="handleDownload" :loading="downloadLoading">{{$t('excel.export')}} excel</el-button>
|
||||||
|
|
||||||
<el-table :data="list" v-loading.body="listLoading" element-loading-text="拼命加载中" border fit highlight-current-row>
|
<el-table :data="list" v-loading.body="listLoading" element-loading-text="拼命加载中" border fit highlight-current-row>
|
||||||
<el-table-column align="center" label='Id' width="95">
|
<el-table-column align="center" label='Id' width="95">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
@@ -45,7 +53,8 @@ export default {
|
|||||||
list: null,
|
list: null,
|
||||||
listLoading: true,
|
listLoading: true,
|
||||||
downloadLoading: false,
|
downloadLoading: false,
|
||||||
filename: ''
|
filename: '',
|
||||||
|
autoWidth: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
@@ -66,7 +75,12 @@ export default {
|
|||||||
const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time']
|
const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time']
|
||||||
const list = this.list
|
const list = this.list
|
||||||
const data = this.formatJson(filterVal, list)
|
const data = this.formatJson(filterVal, list)
|
||||||
excel.export_json_to_excel(tHeader, data, this.filename)
|
excel.export_json_to_excel({
|
||||||
|
header: tHeader,
|
||||||
|
data,
|
||||||
|
filename: this.filename,
|
||||||
|
autoWidth: this.autoWidth
|
||||||
|
})
|
||||||
this.downloadLoading = false
|
this.downloadLoading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -82,3 +96,13 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.radio-label {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #606266;
|
||||||
|
line-height: 40px;
|
||||||
|
padding: 0 12px 0 30px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
@@ -72,7 +72,11 @@ export default {
|
|||||||
const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time']
|
const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time']
|
||||||
const list = this.multipleSelection
|
const list = this.multipleSelection
|
||||||
const data = this.formatJson(filterVal, list)
|
const data = this.formatJson(filterVal, list)
|
||||||
excel.export_json_to_excel(tHeader, data, this.filename)
|
excel.export_json_to_excel({
|
||||||
|
header: tHeader,
|
||||||
|
data,
|
||||||
|
filename: this.filename
|
||||||
|
})
|
||||||
this.$refs.multipleTable.clearSelection()
|
this.$refs.multipleTable.clearSelection()
|
||||||
this.downloadLoading = false
|
this.downloadLoading = false
|
||||||
})
|
})
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-wrapper" :class="{hideSidebar:!sidebar.opened}">
|
<div class="app-wrapper" :class="classObj">
|
||||||
<sidebar class="sidebar-container"></sidebar>
|
<sidebar class="sidebar-container"></sidebar>
|
||||||
<div class="main-container">
|
<div class="main-container">
|
||||||
<navbar></navbar>
|
<navbar></navbar>
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { Navbar, Sidebar, AppMain, TagsView } from './components'
|
import { Navbar, Sidebar, AppMain, TagsView } from './components'
|
||||||
|
import ResizeMixin from './mixin/ResizeHandler'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'layout',
|
name: 'layout',
|
||||||
@@ -20,9 +21,20 @@ export default {
|
|||||||
AppMain,
|
AppMain,
|
||||||
TagsView
|
TagsView
|
||||||
},
|
},
|
||||||
|
mixins: [ResizeMixin],
|
||||||
computed: {
|
computed: {
|
||||||
sidebar() {
|
sidebar() {
|
||||||
return this.$store.state.app.sidebar
|
return this.$store.state.app.sidebar
|
||||||
|
},
|
||||||
|
device() {
|
||||||
|
return this.$store.state.app.device
|
||||||
|
},
|
||||||
|
classObj() {
|
||||||
|
return {
|
||||||
|
hideSidebar: !this.sidebar.opened,
|
||||||
|
withoutAnimation: this.sidebar.withoutAnimation,
|
||||||
|
mobile: this.device === 'mobile'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,17 +2,18 @@
|
|||||||
<div class="menu-wrapper">
|
<div class="menu-wrapper">
|
||||||
<template v-for="item in routes" v-if="!item.hidden&&item.children">
|
<template v-for="item in routes" v-if="!item.hidden&&item.children">
|
||||||
|
|
||||||
<router-link v-if="item.children.length===1 && !item.children[0].children&&!item.alwaysShow" :to="item.path+'/'+item.children[0].path" :key="item.children[0].name">
|
<router-link v-if="hasOneShowingChildren(item.children) && !item.children[0].children&&!item.alwaysShow" :to="item.path+'/'+item.children[0].path"
|
||||||
|
:key="item.children[0].name">
|
||||||
<el-menu-item :index="item.path+'/'+item.children[0].path" :class="{'submenu-title-noDropdown':!isNest}">
|
<el-menu-item :index="item.path+'/'+item.children[0].path" :class="{'submenu-title-noDropdown':!isNest}">
|
||||||
<svg-icon v-if="item.children[0].meta&&item.children[0].meta.icon" :icon-class="item.children[0].meta.icon"></svg-icon>
|
<svg-icon v-if="item.children[0].meta&&item.children[0].meta.icon" :icon-class="item.children[0].meta.icon"></svg-icon>
|
||||||
<span v-if="item.children[0].meta&&item.children[0].meta.title">{{generateTitle(item.children[0].meta.title)}}</span>
|
<span v-if="item.children[0].meta&&item.children[0].meta.title" slot="title">{{generateTitle(item.children[0].meta.title)}}</span>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
||||||
<el-submenu v-else :index="item.name||item.path" :key="item.name">
|
<el-submenu v-else :index="item.name||item.path" :key="item.name">
|
||||||
<template slot="title">
|
<template slot="title">
|
||||||
<svg-icon v-if="item.meta&&item.meta.icon" :icon-class="item.meta.icon"></svg-icon>
|
<svg-icon v-if="item.meta&&item.meta.icon" :icon-class="item.meta.icon"></svg-icon>
|
||||||
<span v-if="item.meta&&item.meta.title">{{generateTitle(item.meta.title)}}</span>
|
<span v-if="item.meta&&item.meta.title" slot="title">{{generateTitle(item.meta.title)}}</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-for="child in item.children" v-if="!child.hidden">
|
<template v-for="child in item.children" v-if="!child.hidden">
|
||||||
@@ -21,7 +22,7 @@
|
|||||||
<router-link v-else :to="item.path+'/'+child.path" :key="child.name">
|
<router-link v-else :to="item.path+'/'+child.path" :key="child.name">
|
||||||
<el-menu-item :index="item.path+'/'+child.path">
|
<el-menu-item :index="item.path+'/'+child.path">
|
||||||
<svg-icon v-if="child.meta&&child.meta.icon" :icon-class="child.meta.icon"></svg-icon>
|
<svg-icon v-if="child.meta&&child.meta.icon" :icon-class="child.meta.icon"></svg-icon>
|
||||||
<span v-if="child.meta&&child.meta.title">{{generateTitle(child.meta.title)}}</span>
|
<span v-if="child.meta&&child.meta.title" slot="title">{{generateTitle(child.meta.title)}}</span>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
</router-link>
|
</router-link>
|
||||||
</template>
|
</template>
|
||||||
@@ -46,6 +47,15 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
hasOneShowingChildren(children) {
|
||||||
|
const showingChildren = children.filter(item => {
|
||||||
|
return !item.hidden
|
||||||
|
})
|
||||||
|
if (showingChildren.length === 1) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
},
|
||||||
generateTitle
|
generateTitle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<scroll-bar>
|
<scroll-bar>
|
||||||
<el-menu mode="vertical" :default-active="$route.path" :collapse="isCollapse" background-color="#304156" text-color="#bfcbd9" active-text-color="#409EFF">
|
<el-menu
|
||||||
|
mode="vertical"
|
||||||
|
:show-timeout="200"
|
||||||
|
:default-active="$route.path"
|
||||||
|
:collapse="isCollapse"
|
||||||
|
background-color="#304156"
|
||||||
|
text-color="#bfcbd9"
|
||||||
|
active-text-color="#409EFF"
|
||||||
|
>
|
||||||
<sidebar-item :routes="permission_routers"></sidebar-item>
|
<sidebar-item :routes="permission_routers"></sidebar-item>
|
||||||
</el-menu>
|
</el-menu>
|
||||||
</scroll-bar>
|
</scroll-bar>
|
||||||
|
@@ -156,7 +156,7 @@ export default {
|
|||||||
.contextmenu {
|
.contextmenu {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
z-index: 2;
|
z-index: 100;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
padding: 5px 0;
|
padding: 5px 0;
|
||||||
|
41
src/views/layout/mixin/ResizeHandler.js
Normal file
41
src/views/layout/mixin/ResizeHandler.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import store from '@/store'
|
||||||
|
|
||||||
|
const { body } = document
|
||||||
|
const WIDTH = 1024
|
||||||
|
const RATIO = 3
|
||||||
|
|
||||||
|
export default {
|
||||||
|
watch: {
|
||||||
|
$route(route) {
|
||||||
|
if (this.device === 'mobile' && this.sidebar.opened) {
|
||||||
|
store.dispatch('closeSideBar', { withoutAnimation: false })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforeMount() {
|
||||||
|
window.addEventListener('resize', this.resizeHandler)
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
const isMobile = this.isMobile()
|
||||||
|
if (isMobile) {
|
||||||
|
store.dispatch('toggleDevice', 'mobile')
|
||||||
|
store.dispatch('closeSideBar', { withoutAnimation: true })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
isMobile() {
|
||||||
|
const rect = body.getBoundingClientRect()
|
||||||
|
return rect.width - RATIO < WIDTH
|
||||||
|
},
|
||||||
|
resizeHandler() {
|
||||||
|
if (!document.hidden) {
|
||||||
|
const isMobile = this.isMobile()
|
||||||
|
store.dispatch('toggleDevice', isMobile ? 'mobile' : 'desktop')
|
||||||
|
|
||||||
|
if (isMobile) {
|
||||||
|
store.dispatch('closeSideBar', { withoutAnimation: true })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user