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 相关文章推荐
jQuery 1.2.x 升? 1.3.x 注意事项
May 06 Javascript
IE中createElement需要注意的一个问题
Jul 13 Javascript
jQeury淡入淡出需要注意的问题
Sep 08 Javascript
javascript自动恢复文本框点击清除后的默认文本
Jan 12 Javascript
Bootstrap导航条可点击和鼠标悬停显示下拉菜单的实现代码
Jun 23 Javascript
Jquery UI实现一次拖拽多个选中的元素操作
Dec 01 Javascript
基于jquery二维码生成插件qrcode
Jan 07 Javascript
jQuery EasyUI Accordion可伸缩面板组件使用详解
Feb 28 Javascript
最新Javascript程序员面试试题和解题方法
Nov 23 Javascript
微信小程序实现图片上传放大预览删除代码
Jun 28 Javascript
微信小程序适配iphoneX的实现方法
Sep 18 Javascript
element-ui 弹窗组件封装的步骤
Jan 22 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网上调查系统
2006/10/09 PHP
smtp邮件发送一例
2006/10/09 PHP
怎样才能成为PHP高手?学会“懒惰”的编程
2006/12/05 PHP
PHPMyAdmin 快速配置方法
2009/05/11 PHP
php过滤敏感词的示例
2014/03/31 PHP
JS判断元素为数字的奇异写法分享
2012/08/01 Javascript
js动态创建标签示例代码
2014/06/09 Javascript
jQuery将所有被选中的checkbox某个属性值连接成字符串的方法
2015/01/24 Javascript
JavaScript中isPrototypeOf函数作用和使用实例
2015/06/01 Javascript
用iframe实现不刷新整个页面上传图片的实例
2016/11/18 Javascript
js禁止浏览器的回退事件
2017/04/20 Javascript
JQuery.dataTables表格插件添加跳转到指定页
2017/06/09 jQuery
使用node.js对音视频文件加密的实例代码
2017/08/30 Javascript
jquery 键盘事件的使用方法详解
2017/09/13 jQuery
JavaScript 异步调用
2017/10/25 Javascript
微信小程序把百度地图坐标转换成腾讯地图坐标过程详解
2019/07/10 Javascript
浅谈vue项目利用Hbuilder打包成APP流程,以及遇到的坑
2020/09/12 Javascript
[03:38]TI4西雅图DOTA2前线报道 71专访
2014/07/08 DOTA
[51:17]完美世界DOTA2联赛循环赛Inki vs DeMonsTer 第二场 10月30日
2020/10/31 DOTA
[53:10]完美世界DOTA2联赛决赛日 FTD vs GXR 第二场 11.08
2020/11/11 DOTA
Django中实现点击图片链接强制直接下载的方法
2015/05/14 Python
python3序列化与反序列化用法实例
2015/05/26 Python
python 用opencv调用训练好的模型进行识别的方法
2018/12/07 Python
基于python2.7实现图形密码生成器的实例代码
2019/11/05 Python
浅谈pytorch中torch.max和F.softmax函数的维度解释
2020/06/28 Python
Python QT组件库qtwidgets的使用
2020/11/02 Python
经典C++面试题一
2016/11/06 面试题
好军嫂事迹材料
2014/01/15 职场文书
安全生产实施方案
2014/02/23 职场文书
农村门前三包责任书
2014/07/25 职场文书
村道德模范事迹材料
2014/08/28 职场文书
无罪辩护词范文
2015/05/21 职场文书
创业计划书之情侣餐厅
2019/09/29 职场文书
详解Python牛顿插值法
2021/05/11 Python
MySQL限制查询和数据排序介绍
2022/03/25 MySQL
python井字棋游戏实现人机对战
2022/04/28 Python