欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-04-10 22:13:27
vue-router的路由变换只存在“变换前”和“变换后”,不存在“切换中”的状态,所以做不到大多数app(微信那样的)在滑动过程中让界面跟随手指移动。但滑动事件还是可以监...

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 手势滑动触发返回功能,希望对大家有所帮助