add sidepanel

This commit is contained in:
Pan 2018-12-06 16:15:04 +08:00
parent 24783ac214
commit 2ea5ec4b51
5 changed files with 176 additions and 12 deletions

View File

@ -0,0 +1,141 @@
<template>
<div ref="rightPanel" :class="{show:show}" class="rightPanel-container">
<div class="rightPanel-background"/>
<div :class="[`rightPanel-${color}`]" class="rightPanel">
<div class="handle-button" type="primary" circle @click="show=!show">
<i :class="show?'el-icon-close':'el-icon-setting'" />
</div>
<div class="rightPanel-items">
<slot/>
</div>
</div>
</div>
</template>
<script>
import { addClass, removeClass } from '@/utils'
export default {
name: 'RightPanel',
props: {
value: {
default: false,
type: Boolean
},
color: {
default: 'primary',
type: String
},
clickNotClose: {
default: false,
type: Boolean
}
},
data() {
return {
show: false
}
},
watch: {
show(value) {
if (value && !this.clickNotClose) {
this.addEventClick()
}
if (value) {
addClass(document.body, 'showRightPanel')
} else {
removeClass(document.body, 'showRightPanel')
}
}
},
mounted() {
this.insertToBody()
},
methods: {
addEventClick() {
window.addEventListener('click', this.closeSidebar)
},
closeSidebar(evt) {
const parent = evt.target.closest('.rightPanel')
if (!parent) {
this.show = false
window.removeEventListener('click', this.closeSidebar)
}
},
insertToBody() {
const elx = this.$refs.rightPanel
const body = document.querySelector('body')
body.insertBefore(elx, body.firstChild)
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
body {
overflow: hidden;
position: relative;
width: calc(100% - 15px);
}
.rightPanel-background {
opacity: 0;
transition: opacity .3s ease;
background: rgba(0, 0, 0, .2);
width: 0;
height: 0;
position: fixed;
z-index: -1;
}
.rightPanel {
background: rgb(255, 255, 255);
z-index: 3000;
position: fixed;
height: 100vh;
width: 100%;
max-width: 260px;
top: 0px;
box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, .05);
left: 0px;
transition: all .25s ease;
transform: translate(100%);
z-index: 40000;
left: auto;
right: 0px;
}
.show {
// transition: all .25s ease;
.rightPanel-background {
z-index: 20000;
opacity: 1;
width: 100%;
height: 100%;
}
.rightPanel {
transform: translate(0);
}
}
.handle-button {
position: absolute;
left: -48px;
border-radius: 4px 0 0 4px !important;
top: 240px;
width: 48px;
height: 48px;
background: #1890ff;
cursor: pointer;
pointer-events: auto;
z-index: 0;
text-align: center;
color: #fff;
line-height: 48px;
i {
font-size: 24px;
line-height: 48px;
}
}
</style>

View File

@ -48,7 +48,13 @@ export default {
* @type {boolean} true | false
* @description Whether only one sub-menu can be active
*/
sidebarUniqueOpened: false
sidebarUniqueOpened: false,
/**
* @type {boolean} true | false
* @description Whether show the settings side-panel
*/
showSettings: false
// permission: true,
// i18n: true

View File

@ -12,7 +12,8 @@ const app = {
size: Cookies.get('size') || settings.size,
viewsTransition: Cookies.get('viewsTransition') || settings.viewsTransition,
needTagsView: Cookies.get('needTagsView') || settings.tagsView,
sidebarUniqueOpened: Cookies.get('sidebarUniqueOpened') || settings.sidebarUniqueOpened
sidebarUniqueOpened: Cookies.get('sidebarUniqueOpened') || settings.sidebarUniqueOpened,
showSettings: settings.showSettings
},
mutations: {
TOGGLE_SIDEBAR: state => {

View File

@ -296,3 +296,16 @@ export function deepClone(source) {
export function uniqueArr(arr) {
return Array.from(new Set(arr))
}
export function hasClass(ele, cls) {
return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'))
}
export function addClass(ele, cls) {
if (!hasClass(ele, cls)) ele.className += ' ' + cls
}
export function removeClass(ele, cls) {
if (hasClass(ele, cls)) {
const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)')
ele.className = ele.className.replace(reg, ' ')
}
}

View File

@ -6,13 +6,18 @@
<navbar/>
<tags-view v-if="needTagsView"/>
<app-main/>
<side-panel v-if="showSettings">
apple
</side-panel>
</div>
</div>
</template>
<script>
import SidePanel from '@/components/SidePanel'
import { Navbar, Sidebar, AppMain, TagsView } from './components'
import ResizeMixin from './mixin/ResizeHandler'
import { mapState } from 'vuex'
export default {
name: 'Layout',
@ -20,16 +25,17 @@ export default {
Navbar,
Sidebar,
AppMain,
TagsView
TagsView,
SidePanel
},
mixins: [ResizeMixin],
computed: {
sidebar() {
return this.$store.state.app.sidebar
},
device() {
return this.$store.state.app.device
},
...mapState({
sidebar: state => state.app.sidebar,
device: state => state.app.device,
needTagsView: state => state.app.needTagsView,
showSettings: state => state.app.showSettings
}),
classObj() {
return {
hideSidebar: !this.sidebar.opened,
@ -37,9 +43,6 @@ export default {
withoutAnimation: this.sidebar.withoutAnimation,
mobile: this.device === 'mobile'
}
},
needTagsView() {
return this.$store.state.app.needTagsView
}
},
methods: {