mui/vue-cli分别实现导航右上角的菜单点击侧滑遮盖在当前页面上

先上效果图
mui/vue-cli分别实现导航右上角的菜单点击侧滑遮盖在当前页面上
点右上角点关闭就能关闭
mui/vue-cli分别实现导航右上角的菜单点击侧滑遮盖在当前页面上
删了一早上代码,这个是从mui的GitHub上面截取的一个干净的框架
附上源码:

<!DOCTYPE html>
<html>

	<head>
		<meta charset="utf-8">
		<title>Hello MUI</title>
		<meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1,user-scalable=no">
		<meta name="apple-mobile-web-app-capable" content="yes">
		<meta name="apple-mobile-web-app-status-bar-style" content="black">

		<link rel="stylesheet" href="../mui/css/mui.min.css">
		<style>
			html,
			body {
				background-color: #efeff4;
			}
			p {
				text-indent: 22px;
			}
			
		</style>
	</head>

	<body>
		<!--侧滑菜单容器-->
		<div id="offCanvasWrapper" class="mui-off-canvas-wrap mui-draggable mui-slide-in">
			<!--菜单部分-->
			<aside id="offCanvasSide" class="mui-off-canvas-right">
				<div id="offCanvasSideScroll" class="mui-scroll-wrapper">
					<div class="mui-scroll">
						侧滑导航						
						<div class="content">
							
							
							<p style="margin: 10px 15px;">
								<button id="offCanvasHide" type="button" class="mui-btn mui-btn-danger mui-btn-block" style="padding: 5px 20px;">关闭侧滑菜单</button>
							</p>

						</div>			
					</div>
				</div>
			</aside>
			<div class="mui-inner-wrap">
				<header class="mui-bar mui-bar-nav">
					<a class="mui-action-back mui-icon mui-icon-back mui-pull-left"></a>
					<a id="offCanvasBtn" href="#offCanvasSide" class="mui-icon mui-action-menu mui-icon-bars mui-pull-right"></a>
					<h1 class="mui-title">左滑导航</h1>
				</header>
				
				<!-- off-canvas backdrop -->
				<div class="mui-off-canvas-backdrop"></div>
			</div>
		</div>
		<script src="../mui/js/mui.min.js"></script>
		<script>
			mui.init({
				swipeBack: false,
			});
			 //侧滑容器父节点
			var offCanvasWrapper = mui('#offCanvasWrapper');
			 //主界面容器
			var offCanvasInner = offCanvasWrapper[0].querySelector('.mui-inner-wrap');
			 //菜单容器
			//var offCanvasSide = document.getElementById("offCanvasSide");
			document.getElementById('offCanvasHide').addEventListener('tap', function() {
				offCanvasWrapper.offCanvas('close');
			});
			 //主界面和侧滑菜单界面均支持区域滚动;
			mui('#offCanvasSideScroll').scroll();
			mui('#offCanvasContentScroll').scroll();
		</script>
	</body>

</html>

二、使用vue-cli做一个侧滑动画
vue-cli中vuex的使用
https://www.cnblogs.com/hopesthwell/p/9256982.html

总结一下:
我们给isShow一个默认的状态让他是false,false是隐藏,true是显示
在mutation里面给他设置规则,什么样的情况isShow是false,什么情况是true
在action里面去提交这两种情况,然后使用 this.$store.dispatch('xxx') 分发
在getters 给他定义一个函数去调用这个isShow
我们在页面是设置v-show="isRellyShow",是否展示就要看计算属性
this.$store.getters.isShowMethod最后我们看到,这个返回的是false,所以就是隐藏
因为我们要实现的效果是点击旁边,让他隐藏,这也就解释了一开始为什么要给他赋值是false

在项目的src文件下新建文件夹store,store之下再新建index.js。
main.js里面引入
mui/vue-cli分别实现导航右上角的菜单点击侧滑遮盖在当前页面上

在store>index.js中的代码结构
下载vuex https://vuex.vuejs.org/zh/installation.html

├── index.html
├── main.js
├── api
│   └── ... # 抽取出API请求
├── components
│   ├── App.vue
│   └── ...
└── store
    ├── index.js          # 我们组装模块并导出 store 的地方
    ├── actions.js        # 根级别的 action
    ├── mutations.js      # 根级别的 mutation
    └── modules
        ├── cart.js       # 购物车模块
        └── products.js   # 产品模块

侧滑菜单
https://blog.****.net/qq_27717857/article/details/79567332
点击右上角菜单后的效果,点左侧遮罩,菜单和遮罩一起消失,右侧要是想滚动overflow: auto;

mui/vue-cli分别实现导航右上角的菜单点击侧滑遮盖在当前页面上

mui/vue-cli分别实现导航右上角的菜单点击侧滑遮盖在当前页面上
Header.vue

<a @click="showSide"></a>
showSide: function () {
      this.$store.dispatch('showSideBar')
    },

Nav.vue

<template>
    <div>
        <Header ></Header>
        <Sidebar></Sidebar>
    </div>
</template>
<script>
import Header from "./Header.vue";
import Sidebar from "./Sidebar.vue";
export default {
    components:{
        Sidebar,Header
    }
}
</script>

Sliderbar.vue

<template>
  <div>
    <transition name="fade" >
      <!-- 这部分功能主要是关闭侧栏菜单,类似一层遮罩的效果 -->
      <div class="menu-mask" v-show="isRellyShow" @click="hideSide"  @touchmove.prevent ></div>
    </transition>

    <transition name="slide-fade">
      <!-- 这里才是侧栏代码部分 -->
      <div class="side-content"  v-show="isRellyShow">
        <!-- css transition动画 加深理解 -->
        
      </div>
    </transition>
  </div>
</template>
<script>
export default {
  methods: {
    hideSide: function() {
      this.$store.dispatch("hideSideBar");
    }
  },
  computed: {
    isRellyShow() {
    //默认是false即隐藏
      return this.$store.getters.isShowMethod;
    }
  }
};
</script>
<style scoped>
.menu-mask {
  width:100%;
  height:100%;
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  opacity: 1;
  z-index: 10;
  background: rgba(0, 0, 0, 0.5);
}
.side-content {
  overflow: auto;
  z-index: 21;
  position: fixed;
  width: 60%;
  height: 100%;
  background: rgb(0, 50, 116);
  top: 0;
  right: 0;
  bottom: 0;
  /* -webkit-overflow-scrolling: touch; */
}
.fade-enter-to,
.fade-leave {
  transition: opacity 0.3s;
}
.fade-enter,
.fade-leave-to {
  opacity: 0;
}
.slide-fade-enter-to,
.slide-fade-leave {
  transition: transform 0.3s;
  transform: translate(0px, 0px);
}
.slide-fade-enter,
.slide-fade-leave-to {
   opacity: 0;
   -webkit-transform: translate(-286px, 0px);
   transform: translate(-286px, 0px);
   -webkit-transition: opacity 0.3s ease-in-out 0.3s,-webkit-transform 0.3s ease-in-out;
   transition: opacity 0.3s ease-in-out 0.3s, transform 0.3s ease-in-out;
}
</style>

Header.vue

<template>
  <header class="mui-bar mui-bar-nav">
      <a class="mui-action-back mui-icon mui-icon-back mui-pull-left">
        <img class="logo-left" src="../../assets/images/左边箭头.png" alt>
      </a>
      <a      
        @click="showSide"
        slot="overwrite-left"
        type="navicon"
        size="35"
        style="fill:#fff;"
        class="mui-icon mui-action-menu mui-icon-bars mui-pull-right"
      >
        <img class="logo-right" src="../../assets/images/菜单.png" alt>
      </a>
      <h1 class="mui-title">
        <div class="start">
          <span class="site">无锡</span>
          <span class="time">1.29 15:05</span>
        </div>
        <div class="middle">
          <span class="site">
            <img class="flight" src="../../assets/images/flight.png" alt>
          </span>
          <span class="time">通程 贵阳</span>
        </div>
        <div class="start">
          <span class="site">大阪</span>
          <span class="time">1.29 18:10</span>
        </div>
      </h1>
    </header>
</template>

<script>
export default {
  methods: {
    showSide: function() {
      this.$store.dispatch("showSideBar");
    }
  },
};
</script>

<style>
/* 导航栏*/
* {
  outline: none;
  margin: 0;
  padding: 0;
}

.mui-bar {
  z-index: 10;
  right: 0;
  left: 0;
  height: 44px;
  /* border-bottom: 1px solid rgb(118, 130, 151); */
  background-color: #fff;
  backface-visibility: hidden;
  /* box-shadow: 0px 0px 10px 5px rgb(214, 213, 213); */
  margin-bottom: 5px;
}

.mui-bar-nav {
  top: 0;
}

.mui-bar-nav.mui-bar .mui-icon {
  padding-right: 10px;
  padding-left: 10px;
}

.mui-bar .mui-icon {
  font-size: 24px;
  position: relative;
  z-index: 20;
  padding-top: 10px;
  padding-bottom: 10px;
}

.mui-icon {
  font-family: Muiicons;
  font-weight: 400;
  font-style: normal;
  line-height: 1;
  display: inline-block;
  text-decoration: none;
  -webkit-font-smoothing: antialiased;
}

.mui-pull-left {
  float: left;
}

.mui-pull-right {
  float: right;
}

a {
  text-decoration: none;
  color: #007aff;
}

a {
  background: 0 0;
}

.mui-bar .mui-title {
  right: 40px;
  left: 40px;
  display: inline-block;
  overflow: hidden;
  width: auto;
  margin: 0;
  text-overflow: ellipsis;
}

.mui-title {
  font-size: 17px;
  font-weight: 500;
  line-height: 25px;
  position: absolute;
  padding: 0;
  text-align: center;
  white-space: nowrap;
  color: #000;
  margin: 0 auto;
}

.logo-left,
.logo-right {
  vertical-align: top;
  width: 24px;
  height: 24px;
}

.start {
  height: 44px;
  width: 80px;
  display: inline-block;
  /* border: 1px solid #cdcdcd; */
}

.middle {
  height: 44px;
  width: 50px;
  display: inline-block;
  /* border: 1px solid #cdcdcd; */
}

.site {
  display: block;
  height: 25px;
  font-size: 15px;
  font-weight: 700;
}

.flight {
  width: 22px;
  margin: 0;
  padding: 0;
}

.time {
  height: 10px;
  display: block;
  font-size: 12px;
  color: rgb(149, 169, 191);
  line-height: 18px;
}

.fly {
  height: 10px;
  display: block;
  font-size: 12px;
  color: rgb(149, 169, 191);
  line-height: 18px;
  margin-top: 3px;
  margin-bottom: 3px;
}
.logo {
  width: 44px;
  position: relative;
  left: -10px;
}
</style>

src里面新建文件夹store新建index.js

import Vuex from 'vuex'
import Vue from 'vue'
Vue.use(Vuex)

// 通过在根实例main.js中注册 store 选项,该 store 实例会注入到根组件下的所有子组件中,且子组件能通过 this.$store 访问到
const state = {
  isShow: false
}

// getters可以被认为是 store 的计算属性
// Getter 会暴露为 store.getters 对象,你可以以属性的形式访问这些值:
const getters = {
  isShowMethod (state) {
    return state.isShow
  }
}

// Action 类似于 mutation,不同在于:
// Action 提交的是 mutation,而不是直接变更状态。
// 使用 this.$store.dispatch('xxx') 分发 action
const actions = {
  showSideBar ({ commit }) {
    commit('showBar')
  },
  hideSideBar ({ commit }) {
    commit('hideBar')
  }
}

// 更改 Vuex 的 store 中的状态的唯一方法是提交 mutation ,即store.commit('showBar')
const mutations = {
  showBar (state) {
    state.isShow = true
  },
  hideBar (state) {
    state.isShow = false
  }
}

export default new Vuex.Store({
  state,
  getters,
  actions,
  mutations
})

这里注意,页面从右往左划是这样的
transform: translate(286px, 0px);
页面从左往右划是这样的
transform: translate(-286px, 0px);