vue-router 手势滑动触发返回功能


Posted in Javascript onSeptember 30, 2018

vue-router的路由变换只存在“变换前”和“变换后”,不存在“切换中”的状态,所以做不到大多数app(微信那样的)在滑动过程中让界面跟随手指移动。但滑动事件还是可以监听的,我们可以在滑动之后再触发路由回退事件。

微博的滑动返回基本上就是这样的原理:先滑动、再触发返回事件,但用起来很是怪异,有严重的滞后感。夸克浏览器做的就比较好:一是滑动时界面虽然不动,但是界面上有小图标提示,能让用户接受到反馈;二是返回过程很快,没有多余的过渡动画。

app.vue文件如下:

<template>
 <div id="app" v-on:touchstart="bodyTouchStart" v-on:touchmove="bodyTouchMove" v-on:touchend="bodyTouchEnd">
 <transition :name="direction">
  <keep-alive include="home">
  <router-view class="appView"></router-view>
  </keep-alive>
 </transition>
 </div>
</template>

<script>
var swidth = document.documentElement.clientWidth;

export default {
 name: 'app',
 data: () => ({
 // direction 页面切换的过渡动画,配合transition组件使用
 direction: "slide-left",
 // touchLeft 划动起点界限,起点在靠近屏幕左侧时才有效
 touchLeft: swidth*2/5,
 // touchStartPoint 记录起始点X坐标
 touchStartPoint: 0,
 // distance 记录划动的距离
 distance: 0,
 // 回退按钮的dom,根据页面上是否存在此dom来判断该路由是否可回退
 backBtn: null
 }),

 watch: {
 // 监听路有变化,决定页面过渡动画
 $route(to, from) {
  if (from.name == "login" || from.path.indexOf("home") > -1) {
  this.direction = "slide-left";
  } else if (to.path.indexOf("home") > -1) {
  this.direction = "slide-right";
  } else {
  const toDepth = to.path.split("/").length;
  const fromDepth = from.path.split("/").length;
  this.direction = toDepth < fromDepth ? "slide-right" : "slide-left";
  }
 }
 },

 methods: {
 bodyTouchStart: function(event) {
  this.backBtn = document.getElementById("navback");
  if (this.backBtn) {
  // 获得起点X坐标,初始化distance为0
  this.touchStartPoint = event.targetTouches[0].pageX;
  this.distance = 0;
  }
 },
 bodyTouchMove: function(event) {
  if (this.backBtn && this.touchStartPoint < this.touchLeft) {
  // 只监听单指划动,多指划动不作响应
  if (event.targetTouches.length > 1) {
   return;
  }
  // 实时计算distance
  this.distance = event.targetTouches[0].pageX - this.touchStartPoint;
  // 根据distance在页面上做出反馈。这里演示通过返回按钮的背景变化作出反馈
  if (this.distance > 0 && this.distance < 100) {
   this.backBtn.style.backgroundPosition = ((this.distance - 100) / 100) * 50 + "px 0";
  } else if (this.distance >= 100) {
   this.backBtn.style.backgroundPosition = "0 0";
  } else {
   this.backBtn.style.backgroundPosition = "-50px 0";
  }
  }
 },
 bodyTouchEnd: function(event) {
  if (this.backBtn && this.touchStartPoint < this.touchLeft) {
  // 划动结束,重置数据
  this.touchStartPoint = 0;
  this.backBtn.style.backgroundPosition = "-50px 0";
  // 当划动距离超过100px时,触发返回事件
  if (this.distance > 100) {
   // 返回前修改样式,让过渡动画看起来更快
   document.getElementById("app").classList.add("quickback");
   this.$router.back();
   setTimeout(function(){
   document.getElementById("app").classList.remove("quickback");
   },250)
  }
  }
 }
 }
}
</script>

<style>
#app {
 -webkit-font-smoothing: antialiased;
 -moz-osx-font-smoothing: grayscale;
 width: 100%;
 overflow-x: hidden;
}
.appView {
 position: absolute;
 width: 100%;
 background: #fff;
 min-height: 100vh;
 transition: transform 0.24s ease-out;
}
#app.quickback .appView{
 transition-duration: 0.1s;
}
.slide-left-enter {
 transform: translate(100%, 0);
}
.slide-left-leave-active {
 transform: translate(-50%, 0);
}
.slide-right-enter {
 transform: translate(-50%, 0);
}
.slide-right-leave-active {
 transform: translate(100%, 0);
}
</style>

下面看下vue图片左右滑动及手势缩放

引入vue-awesome-swiperimport 'swiper/dist/css/swiper.css';

import { swiper, swiperSlide } from 'vue-awesome-swiper';components: {
 swiper,
 swiperSlide,
},data() {
 return {
 swiperOption: {
  width: window.innerWidth,
  zoom : true,
  initialSlide: 0,
 },
 };
},<swiper :options="swiperOption" ref="imgOverview" style="height: 100%;">
 <swiper-slide v-for="(img, index) in previewImg">
 <div class="swiper-zoom-container">
  <img :src="img" alt="">
 </div>
 </swiper-slide>
</swiper>

代码案例见 https://github.com/yource/VueSPA

总结

以上所述是小编给大家介绍的vue-router 手势滑动触发返回功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
AJAX使用了UpdatePanel后无法使用alert弹出脚本
Apr 02 Javascript
深入理解JavaScript系列(10) JavaScript核心(晋级高手必读篇)
Jan 15 Javascript
JS去掉第一个字符和最后一个字符的实现代码
Feb 20 Javascript
jQuery中index()的用法分析
Sep 05 Javascript
举例讲解JavaScript中关于对象操作的相关知识
Nov 16 Javascript
每天一篇javascript学习小结(Function对象)
Nov 16 Javascript
javascript设计简单的秒表计时器
Sep 05 Javascript
详解AngularJS中module模块的导入导出
Dec 10 Javascript
jQuery+canvas实现的球体平抛及颜色动态变换效果
Jan 28 Javascript
利用Angular.js编写公共提示模块的方法教程
May 28 Javascript
基于JavaScript实现前端数据多条件筛选功能
Aug 19 Javascript
layui前端时间戳转化实例
Nov 15 Javascript
Vue CLI3 开启gzip压缩文件的方式
Sep 30 #Javascript
JS数组实现分类统计实例代码
Sep 30 #Javascript
浅谈微信页面入口文件被缓存解决方案
Sep 29 #Javascript
vue实现弹框遮罩点击其他区域弹框关闭及v-if与v-show的区别介绍
Sep 29 #Javascript
vue使用v-for实现hover点击效果
Sep 29 #Javascript
vue 利用路由守卫判断是否登录的方法
Sep 29 #Javascript
vue路由事件beforeRouteLeave及组件内定时器的清除方法
Sep 29 #Javascript
You might like
php获取远程文件大小
2015/10/20 PHP
windows7配置Nginx+php+mysql的详细教程
2016/09/04 PHP
PHP 二维array转换json的实例讲解
2018/08/21 PHP
Prototype Date对象 学习
2009/07/12 Javascript
仿当当网淘宝网等主流电子商务网站商品分类导航菜单
2013/09/25 Javascript
JavaScript实现强制重定向至HTTPS页面
2015/06/10 Javascript
js实现仿Discuz文本框弹出层效果
2015/08/13 Javascript
Node.js中使用socket创建私聊和公聊聊天室
2015/11/19 Javascript
javascript事件模型介绍
2016/05/31 Javascript
JavaScript的instanceof运算符学习教程
2016/06/08 Javascript
Vue2.0 实现单选互斥的方法
2018/04/13 Javascript
Python模拟登录12306的方法
2014/12/30 Python
Django中实现点击图片链接强制直接下载的方法
2015/05/14 Python
Python中http请求方法库汇总
2016/01/06 Python
Python操作RabbitMQ服务器实现消息队列的路由功能
2016/06/29 Python
浅谈Python类里的__init__方法函数,Python类的构造函数
2016/12/10 Python
详解Python3中字符串中的数字提取方法
2017/01/14 Python
Python微信企业号开发之回调模式接收微信端客户端发送消息及被动返回消息示例
2017/08/21 Python
Django的分页器实例(paginator)
2017/12/01 Python
tensorflow实现逻辑回归模型
2018/09/08 Python
python matlab库简单用法讲解
2020/12/31 Python
CSS3的颜色渐变效果的示例代码
2017/09/29 HTML / CSS
Html5 postMessage实现跨域消息传递
2016/03/11 HTML / CSS
软件测试面试题
2014/01/05 面试题
会计应聘求职信范文
2013/12/17 职场文书
优秀广告词大全
2014/03/19 职场文书
婚前协议书范本
2014/04/15 职场文书
群众路线对照检查材料思想汇报怎么写
2014/09/18 职场文书
领导班子三严三实心得体会
2014/10/13 职场文书
销售经理工作检讨书
2015/02/19 职场文书
企业安全隐患排查治理制度
2015/08/05 职场文书
培训感想范文
2015/08/07 职场文书
社区服务理念口号
2015/12/25 职场文书
《假如》教学反思
2016/02/17 职场文书
《神奇的鸟岛》教学反思
2016/02/22 职场文书
2016年党员公开承诺书范文
2016/03/24 职场文书