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>
相关推荐
用户48062260414158 小时前
使用uniapp开发微信小程序-框架搭建
微信小程序·uni-app
TttHhhYy10 小时前
uniapp+vue开发app,蓝牙连接,蓝牙接收文件保存到手机特定文件夹,从手机特定目录(可自定义),读取文件内容,这篇首先说如何读取,手机目录如何寻找
开发语言·前端·javascript·vue.js·uni-app
Funky_oaNiu10 小时前
uniapp实现按钮防重复点击(防抖)完整解决方案
uni-app
原克技术10 小时前
uniapp验证码
uni-app
web150850966411 天前
在uniapp Vue3版本中如何解决webH5网页浏览器跨域的问题
前端·uni-app
何极光2 天前
uniapp小程序样式穿透
前端·小程序·uni-app
User_undefined2 天前
uniapp Native.js 调用安卓arr原生service
android·javascript·uni-app
流氓也是种气质 _Cookie2 天前
uniapp blob格式转换为video .mp4文件使用ffmpeg工具
ffmpeg·uni-app
爱笑的眼睛112 天前
uniapp 极速上手鸿蒙开发
华为·uni-app·harmonyos
鱼樱前端3 天前
uni-app框架核心/常用API梳理一(数据缓存)
前端·uni-app