写点什么

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

  • 2022 年 2 月 26 日
  • 本文字数:2211 字

    阅读完需:约 7 分钟

跨平台应用开发进阶(五) :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进阶(幺贰柒):插槽详解》。


<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>
复制代码


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


<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
用户头像

No Silver Bullet 2021.07.09 加入

岂曰无衣 与子同袍

评论

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