# Vue2怎么实现左滑删除功能 ## 前言 在移动端应用开发中,列表项的交互操作是用户体验的重要组成部分。左滑删除作为一种常见的交互模式,能够让用户在不占用额外空间的情况下快速执行删除操作。本文将详细介绍如何在Vue2中实现这一功能,涵盖从基础实现到性能优化的完整方案。 --- ## 一、功能需求分析 ### 1.1 核心交互逻辑 - **手势识别**:监听touchstart、touchmove、touchend事件 - **位移计算**:根据手指滑动距离控制元素位移 - **阈值判断**:滑动超过阈值自动完成删除,未超过则回弹 - **动画效果**:添加过渡动画提升体验 ### 1.2 技术实现要点 ```javascript // 示例数据结构 data() { return { list: [ { id: 1, text: '项目1', offsetX: 0 }, { id: 2, text: '项目2', offsetX: 0 } ], startX: 0, currentId: null } }
<template> <div class="list-container"> <div v-for="item in list" :key="item.id" class="list-item" @touchstart="handleTouchStart($event, item.id)" @touchmove="handleTouchMove($event, item.id)" @touchend="handleTouchEnd($event, item.id)" :style="{ transform: `translateX(${item.offsetX}px)` }" > <div class="content">{{ item.text }}</div> <div class="delete-btn" @click="handleDelete(item.id)">删除</div> </div> </div> </template>
.list-container { overflow: hidden; } .list-item { position: relative; display: flex; height: 60px; transition: transform 0.3s ease; } .content { flex: 1; background: #fff; padding: 0 15px; line-height: 60px; } .delete-btn { width: 80px; background: #ff4d4f; color: white; text-align: center; line-height: 60px; }
methods: { handleTouchStart(e, id) { this.startX = e.touches[0].clientX this.currentId = id }, handleTouchMove(e, id) { if (id !== this.currentId) return const currentX = e.touches[0].clientX const diffX = currentX - this.startX // 限制只允许左滑 if (diffX < 0) { const item = this.list.find(item => item.id === id) item.offsetX = Math.max(diffX, -80) // 限制最大滑动距离 } }, handleTouchEnd(e, id) { const item = this.list.find(item => item.id === id) if (item.offsetX < -40) { // 超过一半自动完成 item.offsetX = -80 } else { // 否则回弹 item.offsetX = 0 } this.currentId = null }, handleDelete(id) { this.list = this.list.filter(item => item.id !== id) } }
// 使用lodash的节流函数 import { throttle } from 'lodash' methods: { handleTouchMove: throttle(function(e, id) { // 原有逻辑 }, 16) // 60fps的帧间隔 }
handleTouchStart(e, id) { // 记录初始Y坐标用于判断滑动方向 this.startY = e.touches[0].clientY // 原有逻辑... }, handleTouchMove(e, id) { const currentY = e.touches[0].clientY const diffY = Math.abs(currentY - this.startY) // 垂直滑动超过阈值则取消操作 if (diffY > 10) { this.cancelSwipe(id) return } // 原有水平滑动逻辑... }
/* 使用will-change提升动画性能 */ .list-item { will-change: transform; } /* 回弹动画 */ .rebound { animation: rebound 0.5s cubic-bezier(0.25, 0.1, 0.25, 1); } @keyframes rebound { 0% { transform: translateX(-80px); } 100% { transform: translateX(0); } }
// SwipeDelete.vue export default { props: { items: Array, threshold: { type: Number, default: 40 }, deleteWidth: { type: Number, default: 80 } }, // 方法实现... }
<template> <div class="swipe-container"> <div v-for="(item, index) in items" :key="item.id" class="swipe-item" <!-- 事件绑定... --> > <slot name="content" :item="item" :index="index"></slot> <div class="action-area"> <slot name="action" :item="item" :index="index"> <button @click="$emit('delete', item.id)">删除</button> </slot> </div> </div> </div> </template>
场景:与父容器滚动条冲突
解决方案:
handleTouchMove(e, id) { // 检测是否横向滑动 if (Math.abs(diffX) > Math.abs(diffY)) { e.preventDefault() // 阻止默认滚动行为 // 处理滑动逻辑... } }
问题:数据更新导致DOM重建,滑动状态丢失
解决方案:
// 使用Object.freeze保持引用 this.list = Object.freeze(updatedList) // 或使用Vue.set Vue.set(this, 'list', updatedList)
hammer.js
等手势库// SwipeDelete.vue <template> <!-- 完整模板结构 --> </template> <script> export default { name: 'SwipeDelete', props: { /* 参数配置 */ }, data() { /* 数据状态 */ }, methods: { // 完整方法实现 } } </script> <style scoped> /* 完整样式 */ </style>
// ParentComponent.vue <template> <swipe-delete :items="dataList" @delete="handleItemDelete" > <template #content="{ item }"> <div class="custom-content">{{ item.text }}</div> </template> <template #action> <button class="custom-btn">删除</button> </template> </swipe-delete> </template>
通过修改滑动方向检测逻辑,可实现右滑显示更多操作菜单的功能
methods: { handleDelete(id) { this.$store.dispatch('deleteItem', id) } }
本文详细介绍了在Vue2中实现左滑删除功能的完整方案,从基础实现到高级优化,涵盖了手势处理、动画效果、性能优化等关键技术点。通过组件化封装,可以轻松在不同项目中复用此功能。实际开发中还需根据具体业务需求进行调整,希望本文能为您的开发工作提供有价值的参考。
扩展阅读: - Vue官方事件处理文档 - MDN Touch事件参考 - 移动端性能优化指南 “`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。