济南小程序开发_vue swipeCell滑动单元格(仿微信)的完成示例

vue swipeCell滑动单元格(仿微信)的实现示例       这篇文章主要介绍了vue swipeCell滑动单元格(仿微信)的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧


demo展示:(切换为浏览器调试的手机模式并且再次刷新一次)

 template 
 @touchstart
 v-click-outside="handleClickOutside"
 @click="getClickHandler('cell')" 
 :style="{'transform':
 'translateX('+(offset+(isElastic elasticX:0))+'px)','transition-duration':dragging '0s':'0.6s'}" 
 !-- div ref="cellLeft" @click="getClickHandler('left', true)" 
 div 收藏 /div 
 div 添加 /div 
 /div -- 
 @touchend="onClick()"
 :class="offset 'cell_content':'cell_content_active'" SwipeCell /div 
 div ref="cellRight"
 @click="getClickHandler('right', true)" 
 :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",
 pro凡科抠图: {
 // @deprecated
 // should be removed in next major version, use beforeClose instead
 onClose: 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-api
 open(position) {
 const offset =
 position === 'left' putedLeftWidth : -putedRightWidth;
 this.opened = true;
 this.offset = offset;
 this.$emit('open', {
 position,
 name: this.name,
 // @deprecated
 // should be removed in next major version
 detail: this.name,
 // @exposed-api
 close(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 
 if (isPrevent) {
 this.preventDefault(event, this.stopPropagation);
 this.offset = this.range(
 this.deltaX + this.startOffset,
 -putedRightWidth,
 putedLeftWidth
 //增加弹性
 putedRightWidth this.offset === -putedRightWidth || putedLeftWidth this.offset === putedLeftWidth){
 this.preventDefault(event, this.stopPropagation);
 //弹性系数
 this.elasticX = (this.deltaX + this.startOffset - this.offset)/4;
 }else{
 //上下滑动后取消close
 this.dragging = true;
 this.lockClick = true;
 onTouchEnd() {
 if (this.disabled) {
 return;
 //回弹
 this.elasticX = 0
 if (this.dragging) {
 this.toggle(this.offset 0 'left' : 'right');
 this.dragging = false;
 // compatible with desktop scenario
 setTimeout(() = {
 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' 
 putedRightWidth * threshold
 this.open('right');
 } else if (
 computedLeftWidth 
 direction === 'left' 
 putedLeftWidth * 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 '';

// avoid Vue 2.6 event bubble issues by manually binding events // 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滑动单元格内容请搜索凡科以前的文章或继续浏览下面的

相关阅读