当前位置: 首页 > Web前端 > HTML5

匠心打造Vue侧滑菜单组件

时间:2023-04-06 00:13:36 HTML5

本文介绍一个简单的DrawerLayout(类似Android的DrawerLayout)布局组件实现,基于Vue.js。引入的内容已经制作成vue-drawer-layout组件。前言有兴趣的先用手机扫描这个二维码,或者点我然后点击页面左上角的头像打开抽屉,或者从右向左拖动,就可以看到效果了下面的gif,打开你的手机QQ,是不是很像:)谷歌官方称这种布局为DrawerLayout(抽屉导航栏)。那么我们如何实现呢,正片开始啦!HTML结构页面结构非常简单,有一个抽屉和一个主容器,可以使用插槽在外部自定义内容。

抽屉最初是隐藏在左屏外面的,所以设置left:-100%,这样就隐藏在外面了。使用Touch首先判断浏览器是否支持touchEventletisTouch='ontouchstart'inwindow;让mouseEvents=isTouch?{down:'touchstart',move:'touchmove',up:'touchend',over:'touchstart',out:'touchend'}:{down:'mousedown',move:'mousemove',up:'mouseup',over:'mouseover',out:'mouseout'};绑定触地事件document.addEventListener(mouseEvents.down,initDrag,false);首先定义一些变量,手指按下的x坐标标记为startX,手指在滑动中的位置x坐标标记为nowX,记录抽屉的x坐标偏移量是startPosletstartX,nowX,startPos;触发touchstart时,记录起始位置并绑定touchmove,注意:如果是mouseEvent,使用e.clientX获取当前x坐标,如果是touchEvent,使用e.changedTouches[0].clientX获取x坐标constinitDrag=function(e){startX=e.clientX||e.changedTouches[0].clientX;//记录手指按下的位置startPos=this.pos;//记录抽屉第二个位置document.addEventListener(mouseEvents.move,drag,false);document.addEventListener(mouseEvents.up,removeDrag,false);}.bind(this);constdrag=function(e){nowX=e.clientX||}e.changedTouches[0].clientX;//滑动时手指位置的x坐标letpos=startPos+nowX-startX;pos=Math.min(width,pos);//不能超过滑动的最大值pos=Math.max(0,pos);//不能小于0this.pos=pos;//设置滚动距离为拖动距离}.bind(this);那么,手指滑动的距离为nowX-startX,抽屉当前位置为startPos+nowX-startX,这样抽屉就随着手指向右移动了,不会超过我们设置的最大拖动值区分垂直滑动和水平滑动。接下来,你会发现一个问题。当手指垂直滚动主要内容时,向右滑动手指也会拖出抽屉。这时候你应该做一件事:区分垂直滑动和水平滑动。是手指滑动的方向,绿色箭头表示抽屉可以拖出,红色箭头表示不能拖出(注意红色箭头也有x坐标的偏移)。即当抽屉拖不出来时,应该触发默认事件,比如垂直滚动等。当手指按下触发touchstart时,记录初始位置P0;当手指滑动,触发第一个touchmove时,记录位置P1,此时我们将P0到P1的向量记录为S(原谅我是灵魂画手)很容易看出,当∠θ大于某个值,比如30度,可能是垂直滚动操作,而不是拖动抽屉。所以根据y/x>tan30°可以得到判断条件:if(isVerticle===undefined)isVerticle=Math.abs(nowY-startY)/Math.abs(nowX-startX)>(Math.sqrt(3)/3);当isVerticle为true时,不拖动抽屉移动抽屉。我们利用css3的transition属性让抽屉有过渡动画效果。在这里,写一个移动类。移动过渡变换。3秒轻松。不要忘记添加类Binding,拖动时(跟随手指)不需要过渡动画,但只有在松开手指时才需要过渡动画。所以在绑定touchend事件方法的时候,你mustDothesestepsconstremoveDrag=function(e){if(isVerticle!==undefined){if(!isVerticle){//当确定抽屉被拖动时,输入letpos=this.pos;this.visible=pos>width*3/5//如果当前位置大于总宽度的3/5,则判定所有抽屉展开,否则抽屉弹回隐藏if(this.pos>0&&this.pos{letsupportsPassive=false;try{constopts=Object.defineProperty({},'passive',{get:function(){supportsPassive=true;}});window.addEventListener("test",null,opts);}catch(e){}返回supportsPassive;})();于是我们的绑定事件代码就变成了这个文档的样子。addEventListener(mouseEvents.move,drag,supportsPassive?{passive:true}:false);它有效吗?感兴趣的朋友可以点这里看最后写的国外高手的视频。本文介绍实现抽屉导航栏的主要过程。详细代码已经封装到vue-drawer-layout组件中,支持更丰富的自定义和使用方式。具体文档大家可以访问我的github或者npm官网获取。欢迎大家提出问题,不吝赐教,谢谢!