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里面引入
在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;
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);