uni-app picker组件在弹框出现前回退导致页面卡死

发布于 1周前 作者 itying888 来自 Uni-App

uni-app picker组件在弹框出现前回退导致页面卡死

操作步骤:

  1. 进入内页,点击picker组件
  2. 在picker组件弹框出现前,回退上一个页面
  3. 在上一个页面中,picker弹框出现,关闭弹框,页面卡死

预期结果:

回退上一个页面,不出现picker弹框,页面不卡死

实际结果:

回退上一个页面,出现picker弹框,页面卡死

bug描述:

在页面中点击picker组件,在其底部遮罩弹框出现前,快速回退上一个页面,回退后,picker弹框出现,关闭picker弹框,页面卡死,点不动


| 信息类别       | 信息内容           |
|----------------|--------------------|
| 产品分类       | uniapp/App         |
| PC开发环境     | Windows            |
| PC版本号       | 22621.4317         |
| HBuilderX类型  | 正式               |
| HBuilderX版本  | 4.29               |
| 手机系统       | Android            |
| 手机系统版本   | Android 10         |
| 手机厂商       | 小米               |
| 手机机型       | Redmi 9A           |
| 页面类型       | vue                |
| vue版本        | vue3               |
| 打包方式       | 云端               |
| 项目创建方式   | HBuilderX          |

2 回复

你反馈 vue3 运行 picker 在安卓上有问题,你的 HBuilderX 版本是多少,新建 hello uniapp 工程是否可以复现问题?提供你到单页面源码,我测试一下。展开弹窗之前具体是如何操作的回退上一页,滑动屏幕边缘吗


在uni-app中,picker组件用于提供一个选择器界面,允许用户从一系列选项中进行选择。然而,如果在选择器弹框出现之前用户执行了回退操作(例如点击了返回按钮),可能会导致页面状态不一致,进而引起页面卡死的问题。

这个问题通常与页面生命周期管理、事件监听和处理不当有关。为了避免这种情况,可以采取以下措施:

  1. 确保选择器在合适的时机显示:在显示选择器之前,确保页面状态已经稳定。
  2. 监听页面回退事件:在页面回退时,取消任何未完成的异步操作或隐藏选择器。
  3. 使用try-catch捕获异常:在处理选择器相关逻辑时,使用try-catch结构捕获并处理可能的异常。

以下是一个简化的代码示例,展示了如何在uni-app中安全地使用picker组件,并处理可能的回退情况:

<template>
  <view>
    <button @click="showPicker">选择日期</button>
  </view>
</template>

<script>
export default {
  data() {
    return {
      pickerVisible: false, // 控制picker显示状态
    };
  },
  methods: {
    showPicker() {
      this.pickerVisible = true; // 准备显示picker
      uni.showActionSheet({
        itemList: ['从列表选择'],
        success: (res) => {
          if (res.tapIndex === 0) {
            this.openPicker();
          } else {
            this.pickerVisible = false; // 用户取消,隐藏picker(理论上不需要,因为未打开,但为安全起见)
          }
        },
        fail: (err) => {
          this.pickerVisible = false; // 显示失败,隐藏picker
          console.error('显示picker失败', err);
        },
      });
    },
    openPicker() {
      if (!this.pickerVisible) return; // 如果pickerVisible为false,则不执行后续操作
      uni.picker({
        range: ['2023-01-01', '2023-01-02', '2023-01-03'],
        success: (res) => {
          console.log('选中的值', res.value);
          this.pickerVisible = false; // 选择完成后隐藏picker
        },
        fail: (err) => {
          this.pickerVisible = false; // 选择失败,隐藏picker
          console.error('选择失败', err);
        },
      });
      
      // 监听页面隐藏事件,以防页面回退导致卡死
      const pageHideListener = () => {
        uni.hidePicker(); // 隐藏picker
        uni.offPageHide(pageHideListener); // 移除监听器
      };
      uni.onPageHide(pageHideListener);
    },
  },
};
</script>

在这个示例中,我们使用了pickerVisible变量来控制picker的显示状态,并在页面隐藏时通过监听器隐藏picker,以避免因页面回退导致的潜在问题。同时,通过showActionSheet提供了一个更友好的用户交互界面,允许用户确认是否打开选择器。

回到顶部