1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > vue移动端的UI框架实现侧边菜单插件效果

vue移动端的UI框架实现侧边菜单插件效果

时间:2019-04-25 20:16:09

相关推荐

vue移动端的UI框架实现侧边菜单插件效果

web前端|js教程

菜单,侧边,实现

web前端-js教程

湖南跑胡子源码论坛,git和ubuntu,一个tomcat 多个,网络爬虫红牛,一个简单的php程序,潜江便宜的seo推广多少钱lzw

这次给大家带来vue移动端的UI框架实现侧边菜单插件效果,vue移动端的UI框架实现侧边菜单插件的注意事项有哪些,下面就是实战案例,一起来看一下。

asp源码 二维码,vscode使用库报错,ubuntu+gpsd,本地访问tomcat项目,vmgirls爬虫,php rest框架,学seo学会什么运营,个人网站 织梦模板,织梦新闻模板lzw

最近面试发现很多前端程序员都从来没有写过插件的经验,基本上都是网上百度。所以打算写一系列文章,手把手的教一些没有写过组件的兄弟们如何去写插件。本系列文章都基于VUE,核心内容都一样,会了之后大家可以快速的改写成react、angular或者是小程序等组件。这篇文章是第一篇,写的是一个类似QQ的侧边菜单组件。

php p2p投资网贷源码,ubuntu++打开qt,宝塔tomcat无法访问,vba简单爬虫,php反射机怎么使用,seo记录lzw

开始制作

DOM结构

整体结构中应该存在两个容器:1. 菜单容器 2. 主页面容器;因此当前DOM结构如下:

为了使得菜单内容和主题内容能够定制,我们再给两个容器中加入两个slot插槽:默认插槽中放置主体内容、菜单放置到menu插槽内:

css样式

我项目中使用了scss,代码如下:

@mixin one-screen { position: absolute; left:0; top:0; width:100%; height:100%; overflow: hidden;}.r-slide-menu{ @include one-screen; &-wrap, &-content{ @include one-screen; } &-transition{ -webkit-transition: transform .3s; transition: transform .3s; }}

此时我们就得到了两个绝对定位的容器

javascript

现在开始正式的代码编写了,首先我们理清下交互逻辑:

手指左右滑动的时候主体容器和菜单容器都跟着手指运动运动

当手指移动的距离超过菜单容器宽度的时候页面不能继续向右滑动

当手指向左移动使得菜单和页面的移动距离归零的时候页面不能继续向左移动

当手指释放离开屏幕的时候,页面滑动如果超过一定的距离(整个菜单宽度的比例)则打开整个菜单,如果小于一定距离则关闭菜单

所以现在咱们需要在使用组件的时候能够入参定制菜单宽度以及触发菜单收起关闭的临界值和菜单宽度的比例,同时需要给主体容器添加touch事件,最后我们给菜单容器和主体容器添加各自添加一个控制他们运动的style,通过控制这个style来控制容器的移动

export default { props: { width: { type: String, default: 250 }, ratio: { type: Number, default: 2 } }, data () { return { isMoving: false, transitionClass: \, startPoint: { X: 0, y: 0 }, oldPoint: { x: 0, y: 0 }, move: { x: 0, y: 0 } } }, computed: { wrapStyle () { let style = { width: `${this.width}px`, left: `-${this.width / this.ratio}px`, transform: `translate3d(${this.move.x / this.ratio}px, 0px, 0px)` } return style }, contentStyle () { let style = { transform: `translate3d(${this.move.x}px, 0px, 0px)` } return style } }, methods: { touchstart (e) {}, touchmove (e) {}, touchend (e) {} }}

接下来,我们来实现我们最核心的touch事件处理函数,事件的逻辑如下:

手指按下瞬间,记录下当前手指所触摸的点,以及当前主容器的位置

手指移动的时候,获取到移动的点的位置

计算当前手指所在点移动的X、Y轴距离,如果X移动的距离大于Y移动的距离则判定为横向运动,否则为竖向运动

如果横向运动则判断当前移动的距离是在合理的移动区间(0到菜单宽度)移动,如果是则改变两个容器的位置(移动过程中阻止页面中其他的事件触发)

手指离开屏幕:如果累计移动距离超过临界值则运用动画打开菜单,否则关闭菜单

touchstart (e) { this.oldPoint.x = e.touches[0].pageX this.oldPoint.y = e.touches[0].pageY this.startPoint.x = this.move.x this.startPoint.y = this.move.y this.setTransition()},touchmove (e) { let newPoint = { x: e.touches[0].pageX, y: e.touches[0].pageY } let moveX = newPoint.x - this.oldPoint.x let moveY = newPoint.y - this.oldPoint.y if (Math.abs(moveX) = this.width) { this.move.x = this.width } else if (moveX this.width / this.ratio) ? this.width : 0},setTransition (isTransition = false) { this.transitionClass = isTransition ? -slide-menu-transition : \}

上面,这段核心代码中有一个setTransition

函数,这个函数的作用是在手指离开的时候给容器元素添加transition属性,让容器有一个过渡动画,完成关闭或者打开动画;所以在手指按下去的瞬间需要把容器上的这个transition属性去除,避免滑动过程中出现容器和手指滑动延迟的不良体验。

最后提醒下,代码中使用translate3d而非translate的原因是为了启动移动端手机的动画3D加速,提升动画流畅度。最终代码如下:

export default { props: { width: { type: String, default: 250 }, ratio: { type: Number, default: 2 } }, data () { return { isMoving: false, transitionClass: \, startPoint: { X: 0, y: 0 }, oldPoint: { x: 0, y: 0 }, move: { x: 0, y: 0 } } }, computed: { wrapStyle () { let style = { width: `${this.width}px`, left: `-${this.width / this.ratio}px`, transform: `translate3d(${this.move.x / this.ratio}px, 0px, 0px)` } return style }, contentStyle () { let style = { transform: `translate3d(${this.move.x}px, 0px, 0px)` } return style } }, methods: { touchstart (e) { this.oldPoint.x = e.touches[0].pageX this.oldPoint.y = e.touches[0].pageY this.startPoint.x = this.move.x this.startPoint.y = this.move.y this.setTransition() }, touchmove (e) { let newPoint = { x: e.touches[0].pageX, y: e.touches[0].pageY } let moveX = newPoint.x - this.oldPoint.x let moveY = newPoint.y - this.oldPoint.y if (Math.abs(moveX) = this.width) { this.move.x = this.width } else if (moveX this.width / this.ratio) ? this.width : 0 }, // 点击切换 switch () { this.setTransition(true) this.move.x = (this.move.x === 0) ? this.width : 0 }, setTransition (isTransition = false) { this.transitionClass = isTransition ? -slide-menu-transition : \ } }}@mixin one-screen { position: absolute; left:0; top:0; width:100%; height:100%; overflow: hidden;}.r-slide-menu{ @include one-screen; &-wrap, &-content{ @include one-screen; } &-transition{ -webkit-transition: transform .3s; transition: transform .3s; }}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。