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 相关文章推荐
Prototype使用指南之form.js
Jan 10 Javascript
用js判断用户浏览器是否是XP SP2的IE6
Mar 08 Javascript
转换json格式的日期为Javascript对象的函数
Jul 13 Javascript
获得Javascript对象属性个数的示例代码
Nov 21 Javascript
深入分析Cookie的安全性问题
Mar 01 Javascript
node.js微信公众平台开发教程
Mar 04 Javascript
简单易懂的天气插件(代码分享)
Feb 04 Javascript
jquery仿ps颜色拾取功能
Mar 08 Javascript
Vue中添加过渡效果的方法
Mar 16 Javascript
jquery.masonry瀑布流效果
May 25 jQuery
js+html5实现页面可刷新的倒计时效果
Jul 15 Javascript
jquery实现下载图片功能
Jul 18 jQuery
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代码
2007/03/08 PHP
php入门学习知识点七 PHP函数的基本应用
2011/07/14 PHP
Apache启动报错No space left on device: AH00023该怎么解决
2015/10/16 PHP
yii去掉必填项中星号的方法
2015/12/28 PHP
PHP中抽象类和抽象方法概念与用法分析
2016/05/24 PHP
浅谈PHP的排列组合(如输入a,b,c 输出他们的全部组合)
2017/03/14 PHP
jQuery插件实现表格隔行换色且感应鼠标高亮行变色
2013/09/22 Javascript
jquery mobile的触控点击事件会多次触发问题的解决方法
2014/05/08 Javascript
15款jQuery分布引导插件分享
2015/02/04 Javascript
JavaScript Math.round() 方法
2015/12/18 Javascript
基于jQuery实现的无刷新表格分页实例
2016/02/17 Javascript
深入理解node exports和module.exports区别
2016/06/01 Javascript
基于jQuery实现表格内容的筛选功能
2016/08/21 Javascript
JS与jQuery实现隔行变色的方法
2016/09/09 Javascript
使用 Node.js 模拟滑动拼图验证码操作的示例代码
2017/11/02 Javascript
在vue项目中,使用axios跨域处理
2018/03/07 Javascript
Vue前端开发规范整理(推荐)
2018/04/23 Javascript
详解Vue webapp项目通过HBulider打包原生APP
2018/06/29 Javascript
layui layer select 选择被遮挡的解决方法
2019/09/21 Javascript
[40:16]TFT vs Mski Supermajor小组赛C组 BO3 第二场 6.3
2018/06/04 DOTA
wxPython窗口中文乱码解决方法
2014/10/11 Python
Python中实现switch功能实例解析
2018/01/11 Python
Python虚拟环境的原理及使用详解
2019/07/02 Python
python+OpenCV实现图像拼接
2020/03/05 Python
一套Delphi的笔试题二
2013/05/11 面试题
物业管理求职自荐信
2013/09/25 职场文书
毕业生的自我评价
2013/12/30 职场文书
打架检讨书50字
2014/01/11 职场文书
幼儿园中班新学期寄语
2014/01/18 职场文书
遗嘱继承公证书
2014/04/09 职场文书
大学生村官个人对照检查材料(群众路线)
2014/09/26 职场文书
2015年青年志愿者协会工作总结
2015/04/27 职场文书
师范生小学见习总结
2015/06/23 职场文书
关于环保的宣传稿
2015/07/23 职场文书
公司员工培训管理制度
2015/08/04 职场文书
nginx配置限速限流基于内置模块
2022/05/02 Servers