From 543a9928cf0299af3f67b9d70d3218191f514475 Mon Sep 17 00:00:00 2001 From: Yuga Sun Date: Wed, 25 Apr 2018 22:05:07 +0800 Subject: [PATCH 01/12] feat: add draggable kanban using vue-draggable (#625) --- package.json | 2 +- src/components/Kanban/index.vue | 89 ++++++++++++++++++++++++ src/lang/en.js | 1 + src/lang/zh.js | 1 + src/router/index.js | 3 +- src/views/components-demo/dragKanban.vue | 68 ++++++++++++++++++ 6 files changed, 162 insertions(+), 2 deletions(-) create mode 100644 src/components/Kanban/index.vue create mode 100644 src/views/components-demo/dragKanban.vue diff --git a/package.json b/package.json index 96742a86..b47d5d68 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "vue-multiselect": "2.0.8", "vue-router": "3.0.1", "vue-splitpane": "1.0.2", - "vuedraggable": "2.15.0", + "vuedraggable": "^2.16.0", "vuex": "3.0.1", "xlsx": "^0.11.16" }, diff --git a/src/components/Kanban/index.vue b/src/components/Kanban/index.vue new file mode 100644 index 00000000..c16894eb --- /dev/null +++ b/src/components/Kanban/index.vue @@ -0,0 +1,89 @@ + + + + diff --git a/src/lang/en.js b/src/lang/en.js index c08c88ef..fc0405c9 100644 --- a/src/lang/en.js +++ b/src/lang/en.js @@ -19,6 +19,7 @@ export default { componentMixin: 'Mixin', backToTop: 'BackToTop', dragDialog: 'Drag Dialog', + dragKanban: 'Drag Kanban', charts: 'Charts', keyboardChart: 'Keyboard Chart', lineChart: 'Line Chart', diff --git a/src/lang/zh.js b/src/lang/zh.js index a4cc93d4..41c959c3 100644 --- a/src/lang/zh.js +++ b/src/lang/zh.js @@ -19,6 +19,7 @@ export default { componentMixin: '小组件', backToTop: '返回顶部', dragDialog: '拖拽 Dialog', + dragKanban: '可拖拽看板', charts: '图表', keyboardChart: '键盘图表', lineChart: '折线图', diff --git a/src/router/index.js b/src/router/index.js index a5d704ef..70e51d36 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -112,7 +112,8 @@ export const asyncRouterMap = [ { 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: '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-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' }} ] }, diff --git a/src/views/components-demo/dragKanban.vue b/src/views/components-demo/dragKanban.vue new file mode 100644 index 00000000..2bbab2bd --- /dev/null +++ b/src/views/components-demo/dragKanban.vue @@ -0,0 +1,68 @@ + + + + From b7c807935040d84a728849865ce6a008cb4b94e9 Mon Sep 17 00:00:00 2001 From: Pan Date: Thu, 26 Apr 2018 17:31:37 +0800 Subject: [PATCH 02/12] doc: update package.json --- package.json | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index b47d5d68..d6a955e9 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,6 @@ "description": "A magical vue admin. Typical templates for enterprise applications. Newest development stack of vue. Lots of awesome features", "author": "Pan ", "license": "MIT", - "private": true, "scripts": { "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", @@ -12,6 +11,20 @@ "lint": "eslint --ext .js,.vue src", "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": { "axios": "0.17.1", "clipboard": "1.7.1", From afd255d5bac568df5aa502ce1b039c7bc30a24e3 Mon Sep 17 00:00:00 2001 From: Pan Date: Sun, 29 Apr 2018 22:38:59 +0800 Subject: [PATCH 03/12] fix[el-dargDialog]: fixed drag bug in IE --- src/directive/el-dragDialog/drag.js | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/directive/el-dragDialog/drag.js b/src/directive/el-dragDialog/drag.js index 7d49e4bb..e0b63418 100644 --- a/src/directive/el-dragDialog/drag.js +++ b/src/directive/el-dragDialog/drag.js @@ -2,10 +2,16 @@ export default{ bind(el, binding) { const dialogHeaderEl = el.querySelector('.el-dialog__header') const dragDom = el.querySelector('.el-dialog') - dialogHeaderEl.style = 'cursor:move;' - + dialogHeaderEl.style.cssText += ';cursor:move;' + dragDom.style.cssText += ';top:0px;' // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null); - const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null) + function getStyle(dom, attr) { + if (dom.currentStyle) { + return dom.currentStyle[attr] + } else { + return getComputedStyle(dom, false)[attr] + } + } dialogHeaderEl.onmousedown = (e) => { // 鼠标按下,计算当前元素距离可视区的距离 @@ -13,15 +19,15 @@ export default{ const disY = e.clientY - dialogHeaderEl.offsetTop // 获取到的值带px 正则匹配替换 - let styL, styT + let styL = getStyle(dragDom, 'left') + let styT = getStyle(dragDom, 'top') - // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px - if (sty.left.includes('%')) { - styL = +document.body.clientWidth * (+sty.left.replace(/\%/g, '') / 100) - styT = +document.body.clientHeight * (+sty.top.replace(/\%/g, '') / 100) + if (styL.includes('%')) { + styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100) + styT = +document.body.clientHeight * (+styT.replace(/\%/g, '') / 100) } else { - styL = +sty.left.replace(/\px/g, '') - styT = +sty.top.replace(/\px/g, '') + styL = +styL.replace(/\px/g, '') + styT = +styT.replace(/\px/g, '') } document.onmousemove = function(e) { @@ -30,8 +36,7 @@ export default{ const t = e.clientY - disY // 移动当前元素 - dragDom.style.left = `${l + styL}px` - dragDom.style.top = `${t + styT}px` + dragDom.style.cssText += `;left:${l + styL}px;top:${t + styT}px;` // 将此时的位置传出去 // binding.value({x:e.pageX,y:e.pageY}) From f663b23b29c286ea99d746ec28ead39ade9de4c7 Mon Sep 17 00:00:00 2001 From: Pan Date: Mon, 30 Apr 2018 14:58:08 +0800 Subject: [PATCH 04/12] perf[el-dragDialog]: add the verification of moving edges --- src/directive/el-dragDialog/drag.js | 35 ++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/src/directive/el-dragDialog/drag.js b/src/directive/el-dragDialog/drag.js index e0b63418..aa361c7d 100644 --- a/src/directive/el-dragDialog/drag.js +++ b/src/directive/el-dragDialog/drag.js @@ -4,6 +4,7 @@ export default{ 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) { @@ -18,6 +19,18 @@ export default{ 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') @@ -32,14 +45,24 @@ export default{ document.onmousemove = function(e) { // 通过事件委托,计算移动的距离 - const l = e.clientX - disX - const t = e.clientY - disY + 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:${l + styL}px;top:${t + styT}px;` - - // 将此时的位置传出去 - // binding.value({x:e.pageX,y:e.pageY}) + dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;` } document.onmouseup = function(e) { From 62a9565f86f2cb380e142d185c1bedddf24a9c2a Mon Sep 17 00:00:00 2001 From: xVirus <123161769@qq.com> Date: Wed, 2 May 2018 10:27:48 +0800 Subject: [PATCH 05/12] siderbar.css add namespace (#622) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 原来的普通导航栏样式会使用 siderbar 的样式,背景黑底。 2. 修改后,sidebar 样式不变,普通导航栏可以正常使用。 --- src/styles/sidebar.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/styles/sidebar.scss b/src/styles/sidebar.scss index 36410770..6f1d9df0 100644 --- a/src/styles/sidebar.scss +++ b/src/styles/sidebar.scss @@ -62,8 +62,8 @@ } } } - .nest-menu .el-submenu>.el-submenu__title, - .el-submenu .el-menu-item { + .sidebar-container .nest-menu .el-submenu > .el-submenu__title, + .sidebar-container .nest-menu .el-submenu .el-menu-item { min-width: 180px !important; background-color: $subMenuBg !important; &:hover { From 88429bd809dc78c7f90b67d724337eb659f1a104 Mon Sep 17 00:00:00 2001 From: Pan Date: Wed, 2 May 2018 10:29:21 +0800 Subject: [PATCH 06/12] Fix typo --- src/styles/sidebar.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/styles/sidebar.scss b/src/styles/sidebar.scss index 6f1d9df0..f1f719f6 100644 --- a/src/styles/sidebar.scss +++ b/src/styles/sidebar.scss @@ -63,7 +63,7 @@ } } .sidebar-container .nest-menu .el-submenu > .el-submenu__title, - .sidebar-container .nest-menu .el-submenu .el-menu-item { + .sidebar-container .el-submenu .el-menu-item { min-width: 180px !important; background-color: $subMenuBg !important; &:hover { From 0e4ea0871c73fc204828fb010c47ff958e251e5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8A=B1=E8=A3=A4=E8=A1=A9?= Date: Wed, 2 May 2018 14:43:20 +0800 Subject: [PATCH 07/12] feat[sidebar]: add resonsive sidebar (#636) --- src/store/getters.js | 1 + src/store/modules/app.js | 19 +++++++++++- src/styles/sidebar.scss | 33 ++++++++++++++++++-- src/views/layout/Layout.vue | 14 ++++++++- src/views/layout/mixin/ResizeHandler.js | 41 +++++++++++++++++++++++++ 5 files changed, 104 insertions(+), 4 deletions(-) create mode 100644 src/views/layout/mixin/ResizeHandler.js diff --git a/src/store/getters.js b/src/store/getters.js index 8adc5e81..d68251fd 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -1,6 +1,7 @@ const getters = { sidebar: state => state.app.sidebar, language: state => state.app.language, + device: state => state.app.device, visitedViews: state => state.tagsView.visitedViews, cachedViews: state => state.tagsView.cachedViews, token: state => state.user.token, diff --git a/src/store/modules/app.js b/src/store/modules/app.js index 9eed667c..d89664f8 100644 --- a/src/store/modules/app.js +++ b/src/store/modules/app.js @@ -3,8 +3,10 @@ import Cookies from 'js-cookie' const app = { state: { sidebar: { - opened: !+Cookies.get('sidebarStatus') + opened: !+Cookies.get('sidebarStatus'), + withoutAnimation: false }, + device: 'desktop', language: Cookies.get('language') || 'en' }, mutations: { @@ -15,6 +17,15 @@ const app = { Cookies.set('sidebarStatus', 0) } 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) => { state.language = language @@ -25,6 +36,12 @@ const app = { toggleSideBar({ commit }) { commit('TOGGLE_SIDEBAR') }, + closeSideBar({ commit }, { withoutAnimation }) { + commit('CLOSE_SIDEBAR', withoutAnimation) + }, + toggleDevice({ commit }, device) { + commit('TOGGLE_DEVICE', device) + }, setLanguage({ commit }, language) { commit('SET_LANGUAGE', language) } diff --git a/src/styles/sidebar.scss b/src/styles/sidebar.scss index f1f719f6..d69c4347 100644 --- a/src/styles/sidebar.scss +++ b/src/styles/sidebar.scss @@ -1,11 +1,13 @@ #app { + // 主体区域 .main-container { min-height: 100%; transition: margin-left .28s; margin-left: 180px; } - // 侧边栏 + + // 侧边栏 .sidebar-container { .horizontal-collapse-transition { transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out; @@ -32,6 +34,7 @@ width: 100% !important; } } + .hideSidebar { .sidebar-container { width: 36px !important; @@ -62,7 +65,8 @@ } } } - .sidebar-container .nest-menu .el-submenu > .el-submenu__title, + + .sidebar-container .nest-menu .el-submenu>.el-submenu__title, .sidebar-container .el-submenu .el-menu-item { min-width: 180px !important; background-color: $subMenuBg !important; @@ -73,4 +77,29 @@ .el-menu--collapse .el-menu .el-submenu { 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; + } + } } diff --git a/src/views/layout/Layout.vue b/src/views/layout/Layout.vue index 7c824531..8c2dba8f 100644 --- a/src/views/layout/Layout.vue +++ b/src/views/layout/Layout.vue @@ -1,5 +1,5 @@