跨平台应用开发进阶(五) :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-app中image src动态引用图片不生效问题时,注意去掉src前面的.../@等符号,要从/static开始写图片路径。

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

JS业务逻辑层面 JS业务逻辑层主要涉及View的Touch事件@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 方法的具体应用,详参博文

四、拓展阅读

相关推荐
陈随易36 分钟前
专注飞机 FocusFlight,两个人把番茄钟做成了一趟航班
前端·后端·程序员
总要学点什么1 小时前
第98篇:三维特效-材质线效果——给一条线换十种材质,虚线的图案只填了一半
开发语言·前端·javascript·ecmascript·gis·webgl·材质
10share1 小时前
基于大模型的 i18n 方案:把中文原文当 Key,轻松搞定多语言维护
前端·vue.js
古茗前端团队4 小时前
由 key 引发的思考
前端·javascript·react.js
kyriewen4 小时前
我扫了 422 个仓库,近一半 CI 在裸装依赖
前端·javascript·程序员
鹏多多4 小时前
AI 到底能不能独立做个产品?我拿一个小程序验证了
前端·微信小程序·ai编程
火山引擎开发者社区4 小时前
构建专属的飞书群开发助手,AgentKit Studio 一键部署 DeepSeek Harness Super-Agent
前端
啾咪orJIUMI7 小时前
Vue 3 + 高德地图封装实战:点位、区域、Loca 流光与 Vue 信息窗体
前端·vue.js
掘金者阿豪7 小时前
AI数据库不只是向量检索:从数据语义到库内智能计算的技术演进
前端
梦里寻码7 小时前
我用 NestJS + Vue3 写了一套完整的研发管理系统(58 表 / 229 API / 130 项断言,全开源
前端·后端·算法