vue swipeCell滑动单元格(仿微信)的实现示例_vue.js

来源:脚本之家  责任编辑:小易  

绑定触摸2113事件 touchstart touchmove 监听触摸事件event.touches中触摸点的5261数量在touchmove事件做判定,如果4102 event.touches.length==2 则记录此次两点之间的1653距离:Math.sqrt(Math.pow((x2-x1),2)+Math.pow((y2-y1),2))在手指移动过程中针对每一次的两点距离进行比较。如果相对上次较大则放大,否则缩小。div的缩放通过transform:scale(x)进行控制追问能否给一个能跑的demo , 拜托www.zgxue.com防采集请勿采集本网。

抽离Vant weapp滑动单元格代码改造而成

带有拉动弹性回弹效果

demo展示:https://littaotao.github.io/me/index(切换为浏览器调试的手机模式并且再次刷新一次)

<template><divclass="cell_container"@touchstartv-click-outside="handleClickOutside"@click="getClickHandler('cell')"><div:style="{'transform':'translateX('+(offset+(isElastic?elasticX:0))+'px)','transition-duration':dragging?'0s':'0.6s'}"><!-- <div ref="cellLeft" class="cell_left" @click="getClickHandler('left', true)"><div>收藏</div><div>添加</div></div> --><div@touchend="onClick()":class="offset?'cell_content':'cell_content_active'">SwipeCell</div><div ref="cellRight"class="cell_right"@click="getClickHandler('right', true)"><div:class="type?'divPostion':''"ref="remove":style="{'background':'#ccc','padding-left':'10px','padding-right':10+(isElastic?Math.abs(elasticX/3):0)+'px','transition-duration':dragging?'0s':'0.6s'}">标记</div><div :class="type?'divPostion':''" ref="tag" :style="{'transform': type?'translateX('+(-offset*removeWidth/cellRightWidth-(isElastic?elasticX/3:0))+'px)':'','padding-left':'10px','padding-right':10+(isElastic?Math.abs(elasticX/3):0)+'px','transition-duration':dragging?'0s':'0.6s','background':'#000'}">不再关注</div><div :class="type?'divPostion':''" :style="{'transform': type?'translateX('+(-offset*(removeWidth+tagWidth)/cellRightWidth-(isElastic?elasticX/3*2:0))+'px)':'','padding-left':'10px','padding-right':10+(isElastic?Math.abs(elasticX/3):0)+'px','transition-duration':dragging?'0s':'0.6s'}">删除</div></div></div></div></template><script>import ClickOutside from 'vue-click-outside';import { TouchMixin } from '@/components/mixins/touch';export default{name:"SwipeCell",props: {// @deprecated// should be removed in next major version, use beforeClose insteadonClose: Function,disabled: Boolean,leftWidth: [Number, String],rightWidth: [Number, String],beforeClose: Function,stopPropagation: Boolean,name: {type: [Number, String],default: '',},//type:{type:[Number,String],default:1 //0 常规 1 定位},isElastic:{ //弹性type:Boolean,default:true}},data(){return {offset: 0,dragging: true,//-位移elasticX:0,removeWidth:0,tagWidth:0,cellRightWidth:0,cellLeftWidth:0}},computed: {computedLeftWidth() {return +this.leftWidth || this.getWidthByRef('cellLeft');},computedRightWidth() {return +this.rightWidth || this.getWidthByRef('cellRight');},},mounted() {//防止弹性效果影响宽度this.cellRightWidth = this.getWidthByRef('cellRight');this.cellLeftWidth = this.getWidthByRef('cellLeft');this.removeWidth = this.getWidthByRef('remove');this.tagWidth = this.getWidthByRef('tag');this.bindTouchEvent(this.$el);},mixins: [TouchMixin],directives: {ClickOutside},methods: {getWidthByRef(ref) {if (this.$refs[ref]) {const rect = this.$refs[ref].getBoundingClientRect();//type=1定位时获取宽度为0,为此采用获取子元素宽度之和if(!rect.width){let childWidth = 0;for(const item of this.$refs[ref].children){childWidth += item.getBoundingClientRect().width}return childWidth;}return rect.width;}return 0;},handleClickOutside(e){if(this.opened) this.close()},// @exposed-apiopen(position) {const offset =position === 'left' ? this.computedLeftWidth : -this.computedRightWidth;this.opened = true;this.offset = offset;this.$emit('open', {position,name: this.name,// @deprecated// should be removed in next major versiondetail: this.name,});},// @exposed-apiclose(position) {this.offset = 0;if (this.opened) {this.opened = false;this.$emit('close', {position,name: this.name,});}},onTouchStart(event) {if (this.disabled) {return;}this.startOffset = this.offset;this.touchStart(event);},range(num, min, max) {return Math.min(Math.max(num, min), max);},preventDefault(event, isStopPropagation) {/* istanbul ignore else */if (typeof event.cancelable !== 'boolean' || event.cancelable) {event.preventDefault();}if (this.isStopPropagations) {stopPropagation(event);}},stopPropagations(event) {event.stopPropagation();},onTouchMove(event) {if (this.disabled) {return;}this.touchMove(event);if (this.direction === 'horizontal') {this.dragging = true;this.lockClick = true;const isPrevent = !this.opened || this.deltaX * this.startOffset < 0;if (isPrevent) {this.preventDefault(event, this.stopPropagation);}this.offset = this.range(this.deltaX + this.startOffset,-this.computedRightWidth,this.computedLeftWidth);//增加弹性if(this.computedRightWidth && this.offset === -this.computedRightWidth || this.computedLeftWidth && this.offset === this.computedLeftWidth){//this.preventDefault(event, this.stopPropagation);//弹性系数this.elasticX = (this.deltaX + this.startOffset - this.offset)/4;}}else{//上下滑动后取消closethis.dragging = true;this.lockClick = true;}},onTouchEnd() {if (this.disabled) {return;}//回弹this.elasticX = 0if (this.dragging) {this.toggle(this.offset > 0 ? 'left' : 'right');this.dragging = false;// compatible with desktop scenariosetTimeout(() => {this.lockClick = false;}, 0);}},toggle(direction) {const offset = Math.abs(this.offset);const THRESHOLD = 0.15;const threshold = this.opened ? 1 - THRESHOLD : THRESHOLD;const { computedLeftWidth, computedRightWidth } = this;if (computedRightWidth &&direction === 'right' &&offset > computedRightWidth * threshold) {this.open('right');} else if (computedLeftWidth &&direction === 'left' &&offset > computedLeftWidth * threshold) {this.open('left');} else {this.close();}},onClick(position = 'outside') {this.$emit('click', position);if (this.opened && !this.lockClick) {if (this.beforeClose) {this.beforeClose({position,name: this.name,instance: this,});} else if (this.onClose) {this.onClose(position, this, { name: this.name });} else {this.close(position);}}},getClickHandler(position, stop) {return (event) => {if (stop) {event.stopPropagation();}this.onClick(position);};},}}</script><style lang="stylus" scoped>.cell_container{position: relative;overflow: hidden;line-height: 68px;height:68px;div{height: 100%;.cell_content{height: 100%;width: 100%;text-align: center;}.cell_content_active{height: 100%;width: 100%;text-align: center;&:active{background: #e8e8e8;}}.cell_left,.cell_right{position: absolute;top: 0;height: 100%;display: flex;color: #fff;.divPostion{position: absolute;}div{white-space:nowrap;display: flex;align-items: center;background: #ccc;}}.cell_left{left: 0;transform:translateX(-100%);}.cell_right{right: 0;transform:translateX(100%);}}}</style>

touch.js

import Vue from 'vue';export const isServer=false;const MIN_DISTANCE = 10;const TouchMixinData = { startX: Number, startY: Number, deltaX: Number, deltaY: Number, offsetX: Number, offsetY: Number, direction: String};function getDirection(x,y) { if (x > y && x > MIN_DISTANCE) { return 'horizontal'; } if (y > x && y > MIN_DISTANCE) { return 'vertical'; } return '';}export let supportsPassive = false;export function on( target, event, handler, passive = false) { if (!isServer) { target.addEventListener( event, handler, supportsPassive ? { capture: false, passive } : false ); }}export const TouchMixin = Vue.extend({ data() {TouchMixinData return { direction: '' } ; }, methods: { touchStart() { this.resetTouchStatus(); this.startX = event.touches[0].clientX; this.startY = event.touches[0].clientY; }, touchMove() { const touch = event.touches[0]; this.deltaX = touch.clientX - this.startX; this.deltaY = touch.clientY - this.startY; this.offsetX = Math.abs(this.deltaX); this.offsetY = Math.abs(this.deltaY); this.direction = this.direction || getDirection(this.offsetX, this.offsetY); }, resetTouchStatus() { this.direction = ''; this.deltaX = 0; this.deltaY = 0; this.offsetX = 0; this.offsetY = 0; }, // avoid Vue 2.6 event bubble issues by manually binding events // https://github.com/youzan/vant/issues/3015 bindTouchEvent( el ) { const { onTouchStart, onTouchMove, onTouchEnd } = this; on(el, 'touchstart', onTouchStart); on(el, 'touchmove', onTouchMove); if (onTouchEnd) { on(el, 'touchend', onTouchEnd); on(el, 'touchcancel', onTouchEnd); } }, },});

引入即可!!!

到此这篇关于vue swipeCell滑动单元格(仿微信)的实现示例的文章就介绍到这了,更多相关vue swipeCell滑动单元格内容请搜索真格学网以前的文章或继续浏览下面的相关文章希望大家以后多多支持真格学网! 您可能感兴趣的文章:Vue实现移动端左右滑动效果的方法基于Vue实现页面切换左右滑动效果vue 登录滑动验证实现代码Vue实现滑动拼图验证码功能vue实现一个移动端屏蔽滑动的遮罩层实例使用Vue 实现滑动验证码功能Vue无限滑动周选择日期的组件的示例代码vue移动UI框架滑动加载数据的方法vue开发拖拽进度条滑动组件

问题描述:2113vue 路由页面之间如何用手指进行5261滑动解决方法:1、下载依4102赖:npm intall vue-touch --save -D2、在需要滑动的页面1653添加标签;<v-touch> 注意要宽高,当页面有东西要写入时,可用v-touch 包裹着其他标签;如:<v-touch class="controller" v-on:swipeleft="onSwipeLeft" v-on:swiperight="onSwipeRight">3、methods 中分别写入它们的方法;onSwipeLeft(){。。。。。。。},onSwipeRight(){。。。。。。。}以上这篇vue 路由页面之间实现用手指进行滑动的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。您可能感兴趣的文章:使用Vue-Router 2实现路由功能实例详解vue-router路由与页面间导航实例解析内容来自www.zgxue.com请勿采集。


  • 本文相关:
  • vue.js 中取得后台原生html字符串 原样显示问题的解决方法
  • vue如何实现observer和watcher源码解析
  • vue中的transition封装组件的实现方法
  • vue 点击按钮实现动态挂载子组件的方法
  • 基于vue.js 2.0实现百度搜索框效果
  • vue-cli 为项目设置别名的方法
  • vue中当图片地址无效的时候,显示默认图片的方法
  • 说说vuex的getters属性的具体用法
  • vue-cli3脚手架的配置及使用教程
  • 深入理解vue-cli搭建项目后的目录结构探秘
  • 使用vue实现一个类似input range的滑动条
  • js 判断双手指滑动 应该说是:在vue中如何实现 对d...
  • 微信小程序实现点击模板进入子路由阅读后实现阅读...
  • vuejs或者iview当中表格怎么合并单元格
  • 网站首页网页制作脚本下载服务器操作系统网站运营平面设计媒体动画电脑基础硬件教程网络安全yui.ext相关prototypejqueryangularjsjsonlib_jsjs面向对象extjsmootoolsseajsdojovue.jsbackbone.js其它首页javascriptjavascript类库vue实现移动端左右滑动效果的方法基于vue实现页面切换左右滑动效果vue 登录滑动验证实现代码vue实现滑动拼图验证码功能vue实现一个移动端屏蔽滑动的遮罩层实例使用vue 实现滑动验证码功能vue无限滑动周选择日期的组件的示例代码vue移动ui框架滑动加载数据的方法vue开发拖拽进度条滑动组件vue.js 中取得后台原生html字符串 原样显示问题的解决方法vue如何实现observer和watcher源码解析vue中的transition封装组件的实现方法vue 点击按钮实现动态挂载子组件的方法基于vue.js 2.0实现百度搜索框效果vue-cli 为项目设置别名的方法vue中当图片地址无效的时候,显示默认图片的方法说说vuex的getters属性的具体用法vue-cli3脚手架的配置及使用教程深入理解vue-cli搭建项目后的目录结构探秘vue引用js文件的多种方式(推荐)vue之父子组件间通信实例讲解(prvue props用法详解(小结)简单理解vue中props属性vue元素的隐藏和显示(v-show指令vue.js常用指令汇总(v-if、v-fovue 进阶教程之v-model详解使用vue实现图片上传的三种方式详解vue 路由跳转四种方式 (带参vue实现文件上传功能详解vuejs2.0 如何利用proxytable实现跨域vue中mint-ui环境搭建详细介绍vue循环组件加validate多表单验证的实例vue2.0父子组件及非父子组件之间的通信方vue 如何添加全局函数或全局变量以及单页checkbox在vue中的用法小结vue 配合eiement动态路由,权限验证的方法vue利用canvas实现移动端手写板的方法element ui table(表格)实现点击一行展详解vue中组件的缓存
    免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved