1.监听浏览器窗口变化–mixins: [ResizeMixin]
监听页面路由,路由变化时如果设备是桌面端且侧边栏打开,就去vuex关闭侧边导航栏
import store from '@/store'
const { body } = document
const WIDTH = 992
watch: {
$route(route) {
if (this.device === 'mobile' && this.sidebar.opened) {
store.dispatch('app/closeSideBar', { withoutAnimation: false })
}
}
},
WIDTH > 992是桌面端。反之是移动端
this.device:设备类型(mobile:移动端,desktop:桌面端)
this.sidebar.opened:判断侧边导航栏的关闭和打开
withoutAnimation:判断是否显示动画的类名
添加监听浏览器页面变化的方法
beforeMount() {
window.addEventListener('resize', this.$_resizeHandler)
},
beforeDestroy() {
window.removeEventListener('resize', this.$_resizeHandler)
},
方法
1.判断浏览器页面宽度是否小于992
$_isMobile() {
const rect = body.getBoundingClientRect()
return rect.width - 1 < WIDTH
},
2.根据浏览器宽度是否小于992来决定设备类型,触发toggleDevice方法修改vuex中设备类型,如果是移动端触发closeSideBar关闭侧边导航栏
$_resizeHandler() {
if (!document.hidden) {
const isMobile = this.$_isMobile()
store.dispatch('app/toggleDevice', isMobile ? 'mobile' : 'desktop')
if (isMobile) {
store.dispatch('app/closeSideBar', { withoutAnimation: true })
}
}
}
对应vuex中的操作模块—app.js
import Cookies from 'js-cookie'
const state = {
// ! (逻辑非),会将操作数的布尔值求反,而!! 就是类型转换,将对应的类型转换为boolean型,所以我们看一看,[ ]一次求反 (![]) 返回的就是false,再求反(!![]) 返回的就是true。 最后的比较就变成 true == true 自然结果是 true。
// [] 转为字符串是 "" // String([]) 返回""
// [] 转为数字是 0 // Number([]) 返回0
// [] 转为布尔值是 true // Boolean([]) 返回true
// true 转为数字是 1 // Number(true) 返回1
// false 转为数字是 0 // Number(false) 返回0
sidebar: {
opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
withoutAnimation: false
},
device: 'desktop',
size: Cookies.get('size') || 'medium'
}
const mutations = {
//切换侧边导航栏的开关
TOGGLE_SIDEBAR: state => {
state.sidebar.opened = !state.sidebar.opened
state.sidebar.withoutAnimation = false
if (state.sidebar.opened) {
//如果打开,设置status=1
Cookies.set('sidebarStatus', 1)
} else {
//如果关闭,设置status=0
Cookies.set('sidebarStatus', 0)
}
//刷新后通过cookies保留siderbar.opened状态
},
//关闭侧边导航栏
CLOSE_SIDEBAR: (state, withoutAnimation) => {
Cookies.set('sidebarStatus', 0)
state.sidebar.opened = false
state.sidebar.withoutAnimation = withoutAnimation
},
//切换设备类型
TOGGLE_DEVICE: (state, device) => {
state.device = device
},
//设置主体按钮等组件大小
SET_SIZE: (state, size) => {
state.size = size
Cookies.set('size', size)
}
}
const actions = {
toggleSideBar({ commit }) {
commit('TOGGLE_SIDEBAR')
},
closeSideBar({ commit }, { withoutAnimation }) {
commit('CLOSE_SIDEBAR', withoutAnimation)
},
toggleDevice({ commit }, device) {
commit('TOGGLE_DEVICE', device)
},
setSize({ commit }, size) {
commit('SET_SIZE', size)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
移动端触发侧边导航栏开关(layout—index.vue)
一个占满全屏的蒙板
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
handleClickOutside() {
this.$store.dispatch('app/closeSideBar', { withoutAnimation: false })
}
桌面端触发侧边导航栏开(Navbar.vue)
<hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
toggleSideBar() {
this.$store.dispatch('app/toggleSideBar')
},