跨平台应用开发进阶(五) :uni-app 实现列表项左划操作

一、前言

应用Uni-app开发跨平台移动端App项目时,遇到列表项左划操作需求。经过研读Uni-app门户,发现uni-swipe-action组件可以实现列表项左划操作功能。基础效果如下: 应用该组件能够满足基本的列表项目左划操作功能。完整示例demo请移步《uni-swipe-action组件实现列表项左划操作》下载。

二、优化

在组件封装层面,发觉uni-swipe-action组件并不能很好的满足开发需求,故考虑应用其他解决方案。

视图渲染部分 组件视图渲染层主要渲染列表项左划后的操作栏位,包含自定义图标及操作文字。其中,还涉及vue插槽应用,对于Vue插槽不了解的同学可以参考博文《Vue进阶(幺贰捌):Vue插槽:slot、slot-scope与指令v-slot应用讲解》、《Vue进阶(幺贰柒):插槽详解》。

html 复制代码
<template>
	<view>
		<view class="box-slideLeft" scroll-x="true">
			<view class="touch-item touch-slideLeft " @touchstart="touchS" @touchmove="touchM" @touchend="touchE"
				:style="item_show.txtStyle">
				<slot />
			</view>
			<view class="touch-item del-box-touch-slideLeft cf-shuCenter" @click="delItem(item_show)">
				<image :src="imgSrc" style="width: 48rpx;height: 48rpx;"></image>
				<text class="removeTxt">{{oprTxt}}</text>
			</view>
		</view>
	</view>
</template>

⚠️注意:遇到uni-appimage src动态引用图片不生效问题时,注意去掉src前面的.../@等符号,要从/static开始写图片路径。

javascript 复制代码
<image :src="pngimg" mode="aspectFit"></image>
this.pngimg='/static/img/bigVisbilityyellow.png'

JS业务逻辑层面 JS业务逻辑层主要涉及ViewTouch事件@touchstart、@touchmove、@touchend,通过监听手势划动触发相应事件。

javascript 复制代码
<script>
	export default {
		created: function() {
			//专门处理检查对象中,某字段是否存在的,如果存在返回 true 不存在返回 false
			let that = this;
			let item = that.item;
			if (!item.hasOwnProperty("txtStyle")) {
				this.$set(this.item, 'txtStyle', ''); //不需要初始化了
			}
			this.item_show = this.item;
		},
		watch: {
			item(e) {
				this.item_show = e;
			},
		},
		methods: {
			//点击删除按钮事件
			delItem: function(e) {
				let that = this;
				let data = {
					item: e,
					data: that.data_transit,
				};
				this.$emit('delItem', data);
			},
			touchS: function(e) {
				let that = this;
				if (e.touches.length == 1) {
					//设置触摸起始点水平方向位置
					this.startX = e.touches[0].clientX
				}
				this.$forceUpdate();
			},
			touchM: function(e) {
				let that = this;

				if (e.touches.length == 1) {
					//手指移动时水平方向位置
					var moveX = e.touches[0].clientX;
					//手指起始点位置与移动期间的差值
					var disX = this.startX - moveX;
					var delBtnWidth = this.delBtnWidth;
					var txtStyle = "";
					if (disX == 0 || disX < 0) { //如果移动距离小于等于0,说明向右滑动,文本层位置不变
						txtStyle = "left:0px";
					} else if (disX > 0) { //移动距离大于0,文本层left值等于手指移动距离
						txtStyle = "left:-" + disX + "rpx";
						if (disX >= delBtnWidth) {
							//控制手指移动距离最大值为删除按钮的宽度
							txtStyle = "left:-" + delBtnWidth + "rpx";
						}
					}
					//获取手指触摸的是哪一项
					that.item_show.txtStyle = txtStyle;
				}
				this.$forceUpdate();
			},
			touchE: function(e) {
				let that = this;
				if (e.changedTouches.length == 1) {
					//手指移动结束后水平位置
					var endX = e.changedTouches[0].clientX;
					//触摸开始与结束,手指移动的距离
					var disX = this.startX - endX;
					var delBtnWidth = this.delBtnWidth;
					//如果距离小于删除按钮的1/2,不显示删除按钮
					var txtStyle = disX > delBtnWidth / 2 ? "left:-" + delBtnWidth + "rpx" : "left:0px";
					//获取手指触摸的是哪一项
					that.item_show.txtStyle = txtStyle;
				}
				this.$forceUpdate();
			},
		}
	}
</script>

实现效果如下:

三、问题分析

动态加载数据,组件滑动失效是怎么回事?

因为组件会在加载的时候获取相应的节点信息数据 ,获取需要滑动的距离,所以有时候动态加载数据之后,可能是时机的问题,导致节点信息获取失败 ,那么组件就不能正常滑动。此时,可以通过this.$forceUpdate();强制页面重新渲染解决。

完整组件代码示例,请移步《uni-app列表项实现左划操作功能》下载。

3.1 this.$forceUpdate();

调用强制更新方法this.$forceUpdate()会更新视图和数据,并触发updated生命周期函数。Vue中一些复杂对象的修改,有时并不能被Vue监听到,对于深层次结构数据,可以使用$set方法使之被Vue监听,但如果不想利用$set方法去设置,也可以使用$forceUpdate方法,$forceUpdate可以使Vue组件按照最新数据重新渲染。

有关Vue$set 方法的具体应用,详参博文

四、拓展阅读

相关推荐
崔庆才丨静觅3 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60614 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了4 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅4 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅5 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅5 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment5 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅5 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊6 小时前
jwt介绍
前端
爱敲代码的小鱼6 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax