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
相关推荐
大怪v6 小时前
AI抢饭?前端佬:我要验牌!
前端·人工智能·程序员
新酱爱学习6 小时前
字节外包一年,我的技术成长之路
前端·程序员·年终总结
小兵张健6 小时前
开源 playwright-pool 会话池来了
前端·javascript·github
IT_陈寒9 小时前
Python开发者必知的5大性能陷阱:90%的人都踩过的坑!
前端·人工智能·后端
codingWhat9 小时前
介绍一个手势识别库——AlloyFinger
前端·javascript·vue.js
代码老中医10 小时前
2026年CSS彻底疯了:这6个新特性让我删掉了三分之一JS代码
前端
不会敲代码110 小时前
Zustand:轻量级状态管理,从入门到实践
前端·typescript
踩着两条虫10 小时前
VTJ.PRO 双向代码转换原理揭秘
前端·vue.js·人工智能
扉川川10 小时前
OpenClaw 架构解析:一个生产级 AI Agent 是如何设计的
前端·人工智能
远山枫谷10 小时前
一文理清页面/组件通信与 Store 全局状态管理
前端·微信小程序