跨平台应用开发进阶(五) :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 方法的具体应用,详参博文

四、拓展阅读

相关推荐
EnCi Zheng10 分钟前
M5-markconv自定义CSS样式指南 [特殊字符]
前端·css·python
kyriewen14 分钟前
你的网页慢,用户不说直接走——前端性能监控教你“读心术”
前端·性能优化·监控
广州华水科技15 分钟前
北斗GNSS变形监测在大坝安全监测中的应用与优势分析
前端
前端老石人26 分钟前
前端开发中的 URL 完全指南
开发语言·前端·javascript·css·html
CAE虚拟与现实27 分钟前
五一假期闲来无事,来个前段、后端的说明吧
前端·后端·vtk·three.js·前后端
Sarvartha38 分钟前
三目运算符
linux·服务器·前端
晓晨的博客1 小时前
ROS1录制的bag包转换为ROS2格式
前端·chrome
Wect1 小时前
LeetCode 72. 编辑距离:动态规划经典题解
前端·算法·typescript
donecoding1 小时前
别再让 pnpm 跟着 nvm 跑了!独立安装终极指南
前端·node.js·前端工程化
GISer_Jing1 小时前
AI全栈转型_TS后端学习路线
前端·人工智能·后端·学习