目录
1、完成步骤1和2
1.1、设备处理文件
1.2、主页中引用步骤1.1创建文件
1.3、测试
2、Vuex中定义全局变量 device
2.1、定义 device 变量,并提供修改方法
2.2、提供 device 的get方法
2.3、在进入首页或翻转屏幕时,重新设置 device 的值
3、完成步骤4和5
3.1、修改 index 主页
3.2、移动端样式
4、完成后效果图
实现效果:
步骤:
1、当进入 index 页面, 判断当前设备是否是移动端设备, 在控制台输出一下
2、当 如果设备发生翻转的情况,可能会改变当前设备屏幕的分辨率,因此在发生翻转, 再次判断当前设备是否是移动端设备,在控制台输出一下
3、需要在 Vuex 中使用 全局变量 state.device(值为''mobile''表示移动端, 为"desktop"表示桌面端) 来存储当前的设备,在步骤1的时候 给这个 state.device 赋值,在步骤2时候,判断一下是否要改变 state.device 的值
4、为这个 移动端设备 隐藏侧边栏添加样式
5、动态的给 index 页面侧边栏添加隐藏样式
补充:
如果判断当前设备是 移动设备 还是 桌面端设备 ?
在项目中规定,屏幕分辨率宽度 > 992 算是桌面端设备, 其余的算 移动端设备
新建 src / layout / mixin / ResizeHandle.js 文件, 内容
const { body } = document
const WIDTH = 992 // refer to Bootstrap's responsive design
export default {
beforeMount() {
window.addEventListener('resize', this.$_resizeHandler)
},
beforeDestroy() {
window.removeEventListener('resize', this.$_resizeHandler)
},
mounted() {
const isMobile = this.$_isMobile()
console.log('isMobile=' + isMobile)
},
methods: {
$_isMobile() {
const rect = body.getBoundingClientRect()
return rect.width - 1 < WIDTH
},
$_resizeHandler() {
if (!document.hidden) {
const isMobile = this.$_isMobile()
if (isMobile) {
console.log('当前是移动端设备')
} else {
console.log('当前是桌面端设备')
}
}
}
}
}
在 src / layout / index.vue 文件中
import ResizeMixin from './mixin/ResizeHandler'
mixins: [ResizeMixin]
具体代码:
启动前后端,登录成功后,观察控制台输出,如图:
在 src / store / modules / app.js 文件,新增 device 变量,并提供修改它的方法
import Cookies from 'js-cookie'
const state = {
sidebar: {
opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
withoutAnimation: false
},
device: 'desktop'
}
const mutations = {
TOGGLE_SIDEBAR: state => {
state.sidebar.opened = !state.sidebar.opened
state.sidebar.withoutAnimation = false
if (state.sidebar.opened) {
Cookies.set('sidebarStatus', 1)
} else {
Cookies.set('sidebarStatus', 0)
}
},
CLOSE_SIDEBAR: (state, withoutAnimation) => {
Cookies.set('sidebarStatus', 0)
state.sidebar.opened = false
state.sidebar.withoutAnimation = withoutAnimation
},
TOGGLE_DEVICE: (state, device) => {
state.device = device
}
}
const actions = {
toggleSideBar({ commit }) {
commit('TOGGLE_SIDEBAR')
},
closeSideBar({ commit }, { withoutAnimation }) {
commit('CLOSE_SIDEBAR', withoutAnimation)
},
toggleDevice({ commit }, device) {
commit('TOGGLE_DEVICE', device)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
在 src / store / getter.js 文件中, 添加 device 变量的get方法
const getters = {
roles: state => state.user.roles,
permission_routes: state => state.permission.routes,
sidebar: state => state.app.sidebar,
device: state => state.app.device
}
export default getters
在 src / layout / mixin / ResizeHandler.js 文件
import store from '@/store'
const { body } = document
const WIDTH = 992 // refer to Bootstrap's responsive design
export default {
beforeMount() {
window.addEventListener('resize', this.$_resizeHandler)
},
beforeDestroy() {
window.removeEventListener('resize', this.$_resizeHandler)
},
mounted() {
const isMobile = this.$_isMobile()
/**
* 加载index页面时, 如果是移动端
* 全局的 device 值设置为 mobile
* 全局的 sidebar.open 设置为 false (关闭状态)
*/
if (isMobile) {
store.dispatch('app/toggleDevice', 'mobile')
store.dispatch('app/closeSideBar', { withoutAnimation: true })
}
},
methods: {
$_isMobile() {
const rect = body.getBoundingClientRect()
return rect.width - 1 < WIDTH
},
$_resizeHandler() {
if (!document.hidden) {
const isMobile = this.$_isMobile()
store.dispatch('app/toggleDevice', isMobile ? 'mobile' : 'desktop')
}
}
}
}
在 src / layout / index.vue 中, 动态计算出 device属性, 动态设置页面样式
动态计算出 device属性:
...mapState({
sidebar: state => state.app.sidebar,
device: state => state.app.device
})
动态设置样式:
classObj() {
return {
hideSidebar: !this.sidebar.opened,
// openSidebar: this.sidebar.opened,
// withoutAnimation: this.sidebar.withoutAnimation
// 当设备是移动端时的样式
mobile: this.device === 'mobile'
}
}
具体代码:
在 src / assets / styles / sidebar.scss 文件中,添加 移动端样式
#app {
.main-container {
min-height: 100%;
transition: margin-left .28s;
margin-left: $sideBarWidth;
position: relative;
}
.sidebar-container {
width: $sideBarWidth !important;
background-color: $menuBg;
height: 100%;
position: fixed;
font-size: 0px;
top: 0;
bottom: 0;
left: 0;
overflow: hidden;
z-index: 1001;
.scrollbar-wrapper {
height: 100%;
overflow-x: hidden !important;
.el-scrollbar__wrap {
overflow-x: hidden !important;
}
a {
display: inline-block;
width: 100%;
overflow: hidden;
text-decoration: none;
}
.el-menu {
border: none;
height: 100%;
width: 100% !important;
}
.svg-icon {
margin-right: 16px;
}
}
}
.hideSidebar {
.sidebar-container {
width: 54px !important;
}
.main-container {
margin-left: 54px;
}
.submenu-title-noDropdown {
padding: 0 !important;
position: relative;
.el-tooltip {
padding: 0 !important;
.svg-icon {
margin-left: 20px;
}
}
}
.el-submenu {
overflow: hidden;
&>.el-submenu__title {
padding: 0 !important;
.svg-icon {
margin-left: 20px;
}
.el-submenu__icon-arrow {
display: none;
}
}
}
.el-menu--collapse {
.el-submenu {
&>.el-submenu__title {
&>span {
height: 0;
width: 0;
overflow: hidden;
visibility: hidden;
display: inline-block;
}
}
}
}
}
// mobile responsive
.mobile {
.main-container {
margin-left: 0px;
}
.sidebar-container {
transition: transform .28s;
width: $sideBarWidth !important;
}
&.hideSidebar {
.sidebar-container {
pointer-events: none;
transition-duration: 0.3s;
transform: translate3d(-$sideBarWidth, 0, 0);
}
}
}
}