feat[sidebar]: add resonsive sidebar (#636)

This commit is contained in:
花裤衩 2018-05-02 14:43:20 +08:00 committed by GitHub
parent 88429bd809
commit 0e4ea0871c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 104 additions and 4 deletions

View File

@ -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,

View File

@ -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)
} }

View File

@ -1,10 +1,12 @@
#app { #app {
// 主体区域 // 主体区域
.main-container { .main-container {
min-height: 100%; min-height: 100%;
transition: margin-left .28s; transition: margin-left .28s;
margin-left: 180px; margin-left: 180px;
} }
// 侧边栏 // 侧边栏
.sidebar-container { .sidebar-container {
.horizontal-collapse-transition { .horizontal-collapse-transition {
@ -32,6 +34,7 @@
width: 100% !important; width: 100% !important;
} }
} }
.hideSidebar { .hideSidebar {
.sidebar-container { .sidebar-container {
width: 36px !important; 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 { .sidebar-container .el-submenu .el-menu-item {
min-width: 180px !important; min-width: 180px !important;
background-color: $subMenuBg !important; background-color: $subMenuBg !important;
@ -73,4 +77,29 @@
.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;
}
}
} }

View File

@ -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'
}
} }
} }
} }

View 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 })
}
}
}
}
}