- 创想鸟首页
- 站长之家
- 编程技术
vue swipeCell滑动单元格(仿微信)的实现示例
SEO优化专员
•
•
编程技术 •
阅读 2
这篇文章主要介绍了vue swipeCell滑动单元格(仿微信)的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
抽离Vant weapp滑动单元格代码改造而成
带有拉动弹性回弹效果
demo展示:https://littaotao.github.io/me/index(切换为浏览器调试的手机模式并且再次刷新一次)
<div
class=”cell_container”
@touchstart
v-click-outside=”handleClickOutside”
@click=”getClickHandler(‘cell’)”>
<div
:style=”{‘transform’:
‘translateX(‘+(offset+(isElastic?elasticX:0))+’px)’,’transition-duration’:dragging?’0s’:’0.6s’}”>
<!–
–>
<div
@touchend=”onClick()”
:class=”offset?’cell_content’:’cell_content_active'”>SwipeCell
<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
: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
: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’}”>删除
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 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’ ? this.computedLeftWidth : -this.computedRightWidth;
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 < 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{
//上下滑动后取消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’ &&
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);
};
},
}
}
.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%);
}
}
}
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滑动单元格内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
来源:脚本之家
链接:https://www.jb51.net/article/195575.htm
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。
发布者:SEO优化专员,转转请注明出处:https://www.chuangxiangniao.com/p/900734.html
JavaScript 如何计算文本的行数的实现
上一篇
2025年1月4日 02:05:14
相关推荐
-
美国国家安全局承包商的一名前任雇员8日被控窃取并私藏大量机密文件,目前面临20项刑事指控。 路透社援引美国政府官员的话报道,这可能是美国历史上规模最大的政府机密失窃事件。 私藏量惊人 涉案男子名为哈罗德·马丁,现年52岁,家住美国马里兰州,…
-
初次了解到Linux系统还是在我初中的时候,那时候正是在一个中二年龄,喜欢看小说,对于小说中出现的明显的非现实场景感到十分钦佩、羡慕,并常常幻想自己也有小说主人公那样的本领。那正是在这样一个充满幻想的年纪,我看到了一本关于重生、关于黑客的小…
-
HTTPS加密应用在过去两年间取得了惊人成果,全球互联网超50%的网站流量启用HTTPS加密。然而,100%的加密环境,就等于安全吗?借助免费DV SSL证书,越来越多的恶意软件、钓鱼网站转向100%加密,得以逃避安全工具检测、欺骗用户信任…
-
3月8日,小编从国内知名的嵌入式培训机构——华清远见了解到,当前学习智能硬件开发的年轻人越来越多,当然绝大多数人依然选择了捷径,那就是参加相关的技术培训,以短期达到能从事相关的工作,同时实现自己的价值。 但是,想要真正学习这些IT界的热门课…
-
迅雷凭借强大的下载能力、良好的使用体验以及丰富的服务,成为我们的常用软件,其推出的增值服务“迅雷会员”,也受到很多雷友的欢迎。但很多人估计都不知道,迅雷会员是如何实现高速下载的。今天,小编就跟大家科普一下。 传统下载方式与迅雷下载 传统的下…
-
在学习Linux的开始阶段,我跟大家一样因为没有一点基础,学起来有点吃力,当对Linux有了一定的认知,你就会不断调整你的学习方式方法。并且在学习Linux的时候,记得放下您之前的思维,带着一个“无知”的学习态度去接触Linux,不妨是个很…
-
近日,Firefox 52发布,Firefox 52中仍然坚持以往的态度,打压不安全的HTTP页面,而这次Mozilla带给用户的是HTTP的不安全登陆表单,在任何HTTP页面中,一个全新的“不安全密码警告”将会在用户点击表单时,直接出现在…
-
2017年,你是否有一个小目标,打算在新的一年事业更上一层楼、代码写的更优美、对互联网生态拥有更多宏观的战略性了解? 小编精心挑选2016云栖大会、历届在线技术峰会、云栖技术直播核心资料,只把最好的呈现给你!因为资料集合过于庞大,所以分批放…
-
DWG是我们常用的一种图纸格式,如今DWG文件广泛的应用于各个领域。DWG文件怎么打开?不少小伙伴可能刚接触DWG文件,因此不知道如何打开DWG文件。通过这篇文章,小编就来给大家介绍下简单的DWG文件打开方法以及DWG文件查看器最新版下载。…
-
随着第三次信息浪潮的冲击,web技术在近年来可谓发生了天翻地覆的变革。从单向信息的web1.0时代,逐步过渡到信息和人交互的web2.0再到数据主动与人*的web3.0时代,这些成就无疑归功于Web技术的迅速发展。 Web技术最重要的载体便…
联系我们
156-6553-5169
在线咨询: QQ交谈
邮件:253000106@qq.com
工作时间:周一至周五,9:30-18:30,节假日休息