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 相关文章推荐
使用正则替换变量
May 05 Javascript
jqgrid 简单学习笔记
May 03 Javascript
JQuery教学之性能优化
May 14 Javascript
javascript制作2048游戏
Mar 30 Javascript
Javascript中获取浏览器类型和操作系统版本等客户端信息常用代码
Jun 28 Javascript
原生js实现对Ajax的封装(仿jquery)
Jan 22 Javascript
angularjs点击图片放大实现上传图片预览
Feb 24 Javascript
js实现随机点名系统(实例讲解)
Oct 18 Javascript
Node.js readline 逐行读取、写入文件内容的示例
Mar 01 Javascript
vue中利用Promise封装jsonp并调取数据
Jun 18 Javascript
Vue 权限控制的两种方法(路由验证)
Aug 16 Javascript
原生JavaScript实现的无缝滚动功能详解
Jan 17 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
JSON在PHP中的应用介绍
2012/09/08 PHP
使用PHP导出Word文档的原理和实例
2013/10/21 PHP
PHP数组排序之sort、asort与ksort用法实例
2014/09/08 PHP
php输入数据统一类实例
2015/02/23 PHP
php实现模拟登陆方正教务系统抓取课表
2015/05/19 PHP
PHP常用字符串操作函数实例总结(trim、nl2br、addcslashes、uudecode、md5等)
2016/01/09 PHP
Laravel框架中VerifyCsrfToken报错问题的解决
2017/08/30 PHP
Yii框架视图、视图布局、视图数据块操作示例
2019/10/14 PHP
Laravel 不同生产环境服务器的判断实践
2019/10/15 PHP
深入分析PHP设计模式
2020/06/15 PHP
IE及IE6浏览器中判断JS文件加载成功失败的方法
2015/02/18 Javascript
javascript判断变量是否有值的方法
2015/04/20 Javascript
简介JavaScript中的sub()方法的使用
2015/06/08 Javascript
jQuery实现可高亮显示的二级CSS菜单效果
2015/09/01 Javascript
解决jquery中动态新增的元素节点无法触发事件问题的两种方法
2015/10/30 Javascript
JSON字符串和JSON对象相互转化实例详解
2017/01/05 Javascript
javascript编写简易计算器
2017/05/06 Javascript
PHP7新特性简述
2017/06/11 Javascript
React路由管理之React Router总结
2018/05/10 Javascript
重学JS之显示强制类型转换详解
2019/06/30 Javascript
node.js 基于 STMP 协议和 EWS 协议发送邮件
2021/02/14 Javascript
python进程类subprocess的一些操作方法例子
2014/11/22 Python
python飞机大战pygame碰撞检测实现方法分析
2019/12/17 Python
浅谈keras的深度模型训练过程及结果记录方式
2020/01/24 Python
印尼最大的在线购物网站:MatahariMall.com
2016/08/26 全球购物
简述安装Slackware Linux系统的过程
2012/01/12 面试题
企业文化标语大全
2014/06/10 职场文书
社会实践活动总结范文
2014/07/03 职场文书
关于感恩的演讲稿400字
2014/08/26 职场文书
乡镇四风对照检查材料
2014/08/31 职场文书
迟到检讨书2000字(精选篇)
2014/10/07 职场文书
2014年新教师工作总结
2014/11/08 职场文书
酒店采购员岗位职责
2015/04/03 职场文书
Django使用echarts进行可视化展示的实践
2021/06/10 Python
解决Windows Server2012 R2 无法安装 .NET Framework 3.5
2022/04/29 Servers
JS轻量级函数式编程实现XDM二
2022/06/16 Javascript