uni-swipe-action 从编辑页返回后滑动按钮仍显示的问题

一、问题描述

在 uni-app 二手车小程序首页,车辆列表使用了 uni-swipe-action 组件实现左滑展示「删除」和「编辑」按钮。用户操作流程如下:

  1. 左滑某条车辆,露出「删除」「编辑」按钮
  2. 点击「编辑」,跳转到编辑页面
  3. 保存成功,返回首页

Bug 表现:返回首页后,之前滑开的那条车辆仍然处于展开状态,「删除」「编辑」按钮依然可见,而不是像首次进入页面那样只显示列表本身。

期望行为:从编辑页返回首页时,应重置为初始状态,只看到车辆列表,看不到操作按钮。


二、原因分析

2.1 页面生命周期与状态保持

在 uni-app 中,使用 uni.navigateTo 跳转到编辑页时,首页并不会被销毁,而是被压入页面栈并进入「隐藏」状态。当用户从编辑页返回时,首页会触发 onShow,从隐藏恢复为显示。

问题在于:Vue 组件及其内部状态都被保留 ,包括 uni-swipe-action-item 的展开/收起状态。因此之前滑开的项会保持展开状态。

2.2 原有关闭逻辑的不足

原先的实现思路是:通过 ref 拿到每个 uni-swipe-action-item,调用其 close() 方法关闭:

javascript 复制代码
const closeAllSwipeActions = () => {
  if (swipeItems.value && swipeItems.value.length) {
    swipeItems.value.forEach(item => {
      if (item && typeof item.close === 'function') {
        item.close()
      }
    })
  }
}

但在 @dcloudio/uni-ui 的 swipe-action 实现中:

  • 在微信小程序、H5 等平台,滑动状态由 wxs/renderjs 控制,内部使用 is_show 状态
  • close() 主要供部分非 H5/微信平台使用
  • 官方推荐的关闭方式 是调用父组件 uni-swipe-actioncloseAll() 方法,由父组件统一遍历子组件并设置 vm.is_show = 'none'

因此,直接对子项调用 close() 在上述平台上可能无法正确关闭。

2.3 ref 使用方式的影响

原先把 ref="swipeItems" 写在 v-foruni-swipe-action-item 上,Vue 3 中会得到子组件数组。不同平台下子组件的 API 不完全一致,直接遍历子项调用 close() 的可靠性和兼容性较差。


三、解决方案

3.1 使用父组件的 closeAll API

ref 放在父组件 uni-swipe-action 上,并调用其 closeAll() 方法:

vue 复制代码
<uni-swipe-action ref="swipeActionRef">
  <uni-swipe-action-item
    v-for="car in carList"
    :key="car._id"
    :right-options="getSwipeOptions(car)"
    @click="onSwipeAction($event, car)"
  >
    <!-- 内容 -->
  </uni-swipe-action-item>
</uni-swipe-action>
javascript 复制代码
const swipeActionRef = ref(null)

const closeAllSwipeActions = () => {
  const swipeAction = swipeActionRef.value
  if (swipeAction && typeof swipeAction.closeAll === 'function') {
    swipeAction.closeAll()
  }
}

3.2 在 onShow 中配合 nextTick 调用

从编辑页返回时,onShow 会触发,但此时 DOM 可能尚未完全恢复。使用 nextTick 确保在下次 DOM 更新后再关闭:

javascript 复制代码
onShow(() => {
  nextTick(() => {
    closeAllSwipeActions()
  })
  getCarList()
})

3.3 跳转前主动关闭(可选)

在点击「编辑」跳转前,也调用一次 closeAllSwipeActions(),避免带着展开状态离开页面,有利于状态更一致。


四、知识点小结

要点 说明
页面栈 navigateTo 跳转时原页面不销毁,返回时只是 onShow,组件状态保留
uni-swipe-action 关闭 应通过父组件 uni-swipe-actioncloseAll() 关闭,而非遍历子项调用 close()
ref 使用 父组件统一管理子项状态时,优先对父组件加 ref,调用其对外 API
nextTick 页面恢复显示时,用 nextTick 等 DOM 更新后再操作组件,避免时序问题

五、参考资料

  • uni-swipe-action 插件文档
  • uni-ui 源码:node_modules/@dcloudio/uni-ui/lib/uni-swipe-action/uni-swipe-action.vue
  • uni-ui 源码:node_modules/@dcloudio/uni-ui/lib/uni-swipe-action-item/mpwxs.js
相关推荐
ZC跨境爬虫3 小时前
跟着MDN学HTML_day_48:(Node接口)
前端·javascript·ui·html·音视频
PieroPc4 小时前
CAMWATCH — 局域网摄像头监控系统 Fastapi + html
前端·python·html·fastapi·监控
巴巴博一5 小时前
2026 最新:Trae / Cursor 一键接入 taste-skill 完整教程(让 AI 前端告别“AI 味”)
前端·ai·ai编程
kyriewen5 小时前
半夜三点线上崩了,AI替我背了锅——用AI排错,五分钟定位三年老bug
前端·javascript·ai编程
kyriewen6 小时前
我让 AI 当了 24 小时全年无休的“毒舌考官”
前端·ci/cd·ai编程
hexu_blog6 小时前
vue+java实现图片批量压缩
java·前端·vue.js
IT_陈寒6 小时前
为什么你应该学习JavaScript?
前端·人工智能·后端
lifejump7 小时前
Empire(帝国)CMS 7.5 XSS注入
前端·安全·xss
无风听海7 小时前
OAuth 2.0 前端通道与后端通道深入剖析
前端·oauth
sakiko_7 小时前
UIKit学习笔记8-发送照片、拍摄照片并发送
前端·swift·uikit