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>
相关推荐
耶啵奶膘11 小时前
uniapp+vue2全局监听退出小程序清除缓存
小程序·uni-app
我开心就好o18 小时前
uniapp点左上角返回键, 重复来回跳转的问题 解决方案
前端·javascript·uni-app
Random_index18 小时前
#Uniapp篇:支持纯血鸿蒙&发布&适配&UIUI
uni-app·harmonyos
初遇你时动了情1 天前
uniapp 城市选择插件
开发语言·javascript·uni-app
小小黑0071 天前
uniapp+vue3+ts H5端使用Quill富文本插件以及解决上传图片反显的问题
uni-app·vue
草字1 天前
uniapp input限制输入负数,以及保留小数点两位.
java·前端·uni-app
前端小胡兔1 天前
uniapp rpx兼容平板
uni-app
荔枝吖1 天前
uniapp实现开发遇到过的问题(持续更新中....)
uni-app
艾小逗1 天前
uniapp将图片url转换成base64支持app和h5
uni-app·base64·imagetobase64
halo14161 天前
uni-app 界面TabBar中间大图标设置的两种方法
开发语言·javascript·uni-app