uniapp移动端实现商品拖拽集合,一行多个商品左滑删除功能!

许久未见,最近遇到一个产品,他是第一次做产品。总是有一些反人类的设计。没错,就是标题上的拖拽集合,以及商品的左滑删除。这种功能放眼各大app我都没找到有用这种设计的,他口口声声说他用过会找给我看,我等了许久,或许是他忘记了吧。

遇到这种需求,我也尝试和他沟通,比如使用购物车来删除商品等等,换一些大家都能接受的逻辑,但是他有自己的想法,我只好选择尊重。

1.拖拽集合功能

拖拽集合功能我寻找很久后使用了一款大神写的拖拽插件,并对其进行了相应的适配,因为我这个需求不需要显示上的集合,在集合的时候是跳转页面,所以在使用上会有一些修改,但是总体上是类似的,一下是插件官网,大家可以参考:

vue.draggable中文文档 - itxst.com

注意:在开发的时候监听拖拽开始和结束事件的时候会提示报错,如果有这个建议大家自行解决或者采用和我一样的方式监听拖动过程等,这个因需求而异。最后附上代码:

javascript 复制代码
<template>
	<div id="app">
		<h1>商品列表</h1>
		<div class="container">
			<div class="row">
				<!-- @change="onDragEnd"  @start="start" @end="onEnd" :move="onMove" delay="1000" -->
				<div class="col-md-6">
					<draggable v-model="leftItems" :group="group" delay="1000"
						@change="onDragEnd" :move="onMove"
						animation="300"  dragClass="dragClass" ghostClass="ghostClass">
<!-- 						<u-swipe-action :show="item.show" :index="index" 
							v-for="(item, index) in leftItems" :key="item.id" 
							@click="click" @open="open"
							:options="options"
						> -->
							<div class="item" v-for="(item, index) in leftItems" :key="item.id" >{{ item.name }}</div>
						<!-- </u-swipe-action> -->
					</draggable>
				</div>

				<div class="col-md-6">
					<draggable v-model="rightItems" :group="group"
						@change="onDragEnd" :move="onMove">
						<div v-for="(item, index) in rightItems" :key="index" @longpress="aaa(index)" :class="['item',item.status==true?'shake':'']">{{ item.name }}</div>
					</draggable>
				</div>
			</div>
		</div>
	</div>
</template>
<script>
	import draggable from 'vuedraggable';

	export default {
		components: {
			draggable
		},
		data() {
			return {
				disabled: false,
				btnWidth: 180,
				show: false,
				options: [
					{
						text: '删除',
						style: {
							backgroundColor: '#dd524d'
						}
					}
				],
				timerId: null,//计时器id
				group: {
					name: "itxst",
					pull: true, //可以拖出
					put: true, //可以拖入
				},
				leftItems: [{
						id: 1,
						show: false,
						status: false,
						name: '商品1'
					},
					{
						id: 2,
						show: false,
						status: false,
						name: '商品2'
					},
					{
						id: 3,
						show: false,
						status: false,
						name: '商品3'
					},
					{
						id: 4,
						show: false,
						status: false,
						name: '商品4'
					},
					{
						id: 5,
						show: false,
						status: false,
						name: '商品5'
					},
					{
						id: 6,
						show: false,
						status: false,
						name: '商品6'
					},
				],
				rightItems: [{
						id: 1,
						show: false,
						status: false,
						name: '商品1'
					},
					{
						id: 2,
						show: false,
						status: false,
						name: '商品2'
					},
					{
						id: 3,
						show: false,
						status: false,
						name: '商品3'
					},
					{
						id: 4,
						show: false,
						status: false,
						name: '商品4'
					},
					{
						id: 5,
						show: false,
						status: false,
						name: '商品5'
					},
					{
						id: 6,
						show: false,
						status: false,
						name: '商品6'
					},
				]
			};
		},
		onLoad() {

		},
		methods: {
			click(index) {
				this.leftItems.splice(index, 1);
				this.$u.toast(`删除了第${index}个cell`);
			},
			// 如果打开一个的时候,不需要关闭其他,则无需实现本方法
			open(index) {
				// 先将正在被操作的swipeAction标记为打开状态,否则由于props的特性限制,
				// 原本为false,再次设置为false会无效
				this.leftItems[index].show = true;
				this.leftItems.map((val, idx) => {
					if(index != idx) this.leftItems[idx].show = false;
				})
			},

			start(e) {
				console.log(e, 'kasihi ');
			},
			onEnd() {
				console.log(e, '结束了 ');
			},
			onMove(e) { // keyi huanyuan
				clearTimeout(this.timerId)
				console.log('如果能监听到要在这里清楚计时器');
				return this.canFormSet()
			},
			aaa(index) {
				this.rightItems[index].status = true
				this.timerId = setTimeout(() => {
					this.rightItems[index].status = false
					clearTimeout(this.timerId)
				}, 500)
			},
			onDragEnd(event) {
				console.log(event);
				// if (event.newIndex !== event.oldIndex) {
				// const movedItem = this.leftItems[event.oldIndex];
				// this.leftItems.splice(event.oldIndex, 1);
				// this.rightItems.push(movedItem);
				// 判断是否可以形成集合跳转页面
				if (this.canFormSet()) {
					// 跳转到另一个页面的逻辑
					console.log('路由去往新的页面');
					// this.$router.push('/another-page');
				} else {
					// 如果不能形成集合,则复原
					console.log('复原');

					// this.rightItems.pop();
					// this.leftItems.splice(event.newIndex, 0, movedItem);
				}
				console.log('6666');
				clearTimeout(this.timerId)
				//   } else {
				// console.log('else');
				//     // Revert the move if it's not a valid combination
				//     const movedItem = this.rightItems.pop();
				//     this.leftItems.splice(event.newIndex, 0, movedItem);
				//   }
			},

			canFormSet() {
				// 如果可以形成集合,返回 true;否则返回 false
				return false; // 示例中默认返回 true
			}
		}
	};
</script>

<style scoped lang="scss">
	.shake {
		width: 100px;
		height: 100px;
		background-color: red;
		transform-origin: center;
		animation: shake .5s infinite ease-in-out;
	}

	@keyframes shake {

		0%,
		100% {
			transform: rotate(-5deg);
			/* transform: translate(-50%, -50%) rotate(-5deg); */
		}

		50% {
			transform: rotate(5deg);
		}
	}

	.ghostClass {
		background-color: blue !important;
	}

	.chosenClass {
		background-color: red !important;
		opacity: 1 !important;
	}

	.dragClass {
		background-color: blueviolet !important;
		opacity: 1 !important;
		box-shadow: none !important;
		outline: none !important;
		background-image: none !important;
	}

	.container {
		width: 100%;
		margin-top: 20px;
	}
	.row {
		width: 100%;
		display: flex;
	}
	.col-md-6 {
		width: 100%;
		// display: flex;
		// flex-wrap: wrap;
	}

	.item {
		width: 100px;
		height: 100px;
		margin-left: 20px;
		border: 1px solid #ccc;
		padding: 10px;
		margin-bottom: 10px;
		background-color: #f9f9f9;
	}
</style>

2.一行多个商品滑动删除功能

上面的代码大家也看到了 我计划使用 u-swipe-action 来实现滑动删除功能,但是它只能一行滑动删除。所以我看了一下源码,然后有所顿悟,手搓了一个一行多个的删除效果代码,后期也会进行一些优化,废话不多说,代码给大家参考,希望能帮到你:

javascript 复制代码
<template>
  <view class="container">
    <movable-area class="box-info" 
		v-for="(item, index) in items"
        :key="index">
      <movable-view
        style="width: 140px; height: 100px; background-color: #aa55ff;"
		:style="{widh}"
        :x="index * 10"
        :direction="'horizontal'"
        :out-of-bounds="false"
      >
        <view class="product">
			<view style="width: 100px;">{{item}}</view>
			<view class="move" @click="removeShop">删除</view>
		</view>
      </movable-view>
    </movable-area>
  </view>
</template>

<script>
export default {
  data() {
    return {
      items: ['商品1', '商品2']
    };
  },
  methods: {
    removeShop(index) {
		alert('删除商品操作')
	}
  }
};
</script>

<style scoped lang="scss">
.container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  .box-info {
	display: flex;
	flex-wrap: wrap;
  	height: 100px; 
  	width: 100px; 
  	background-color: #55ff7f;
  	overflow: hidden;
  	margin: 20px;
	.product {
	  display: flex;
	  justify-content: center;
	  align-items: center;
	  font-size: 14px;
	  color: #333;
	  .move{
	  	  background-color: #55aa00;
	  	  width: 40px;
	  	  height: 100px;
	  	  writing-mode: vertical-rl; 
	  	  display: flex;
	  	  justify-content: center;
	  	  align-items: center;
	  }
	}
  }
}
</style>
相关推荐
某公司摸鱼前端32 分钟前
uniapp微信小程序使用ucharts遮挡自定义tabbar的最佳解决方案
微信小程序·小程序·uni-app·echarts·ucharts
小怪瘦7933 分钟前
UniApp基于xe-upload实现文件上传组件
uni-app
风清云淡_A5 小时前
uniapp中检测应用更新的两种方式-升级中心之uni-upgrade-center-app
前端·uni-app
海岛日记5 小时前
uniapp url取消#
java·数据库·uni-app
ZL_5675 小时前
uniapp中实现评分组件,多用于购买商品后,对商品进行评价等场景
前端·javascript·uni-app
家里有只小肥猫5 小时前
uni-app在线预览pdf
pdf·uni-app
diygwcom7 小时前
低代码可视化-UniApp二维码可视化-代码生成器
低代码·uni-app
霸王蟹7 小时前
uniapp中uni.request的统一封装 (ts版)
前端·javascript·vue.js·笔记·uni-app
莫问alicia9 小时前
Uniapp 微信小程序 最新 获取用户头像 和 昵称 方法 有效可用
前端·javascript·微信小程序·uni-app·vue
LeslieChan_专业海外留学服务9 小时前
美本申请怎么填写课外活动?这些细节值得注意
c++·uni-app·c#·oneapi·cmmi·墨刀