Skip to content

[H5][picker] range 异步赋值后快速滑动,选项区域变空白但 DOM 数据仍存在 #6044

Description

@Rechendian

问题描述

uni-app Vue2 项目在 H5 平台使用内置 <picker>。picker 的 range 初始为空数组,页面加载后通过接口异步赋值。

接口返回正常,picker 首次打开时也能显示选项。但在选项区域快速向上滑动,尤其滑到最后一项后继续快速上甩,有概率出现选项区域完全空白。

空白时:

  • “取消”和“完成”仍正常显示;
  • picker 遮罩和弹层仍然存在;
  • DOM 中仍能看到全部选项节点和文本;
  • range 数组没有被清空;
  • 控制台没有对应的 JavaScript 异常。

Chrome 直接运行 H5 和 Flutter WebView 内嵌 H5 均可复现;微信小程序暂未复现。

环境

  • uni-app:Vue2
  • 平台:H5
  • 页面 runtime compilerVersion:5.23
  • 操作系统:Windows
  • 浏览器:Chrome
  • 微信小程序:未复现
  • Flutter WebView:可复现

最小结构

<template>
  <view>
    <picker
      :value="currentIndex"
      :range="options"
      range-key="typeName"
      :disabled="!options.length"
      @change="handleChange"
    >
      <view>
        {{ currentIndex !== null && options[currentIndex]
          ? options[currentIndex].typeName
          : '请选择' }}
      </view>
    </picker>
  </view>
</template>

<script>
export default {
  data() {
    return {
      currentIndex: null,
      options: []
    }
  },

  mounted() {
    // 模拟接口异步返回
    setTimeout(() => {
      this.options = [
        { id: '1', typeName: '固定选项一' },
        { id: '2', typeName: '固定选项二' },
        { id: '3', typeName: '固定选项三' }
      ]
    }, 500)
  },

  methods: {
    handleChange(e) {
      this.currentIndex = Number(e.detail.value)
    }
  }
}
</script>

复现步骤

  1. 在 H5 平台打开页面。
  2. 等待异步数据赋值完成,确认 picker 中已有三个选项。
  3. 打开 picker。
  4. 在选项区域快速向上甩动。
  5. 滑到最后一项后继续快速向上甩动,重复数次。
  6. 选项区域有概率完全变空白。

实际结果

picker 选项区域空白,但 range 数据及对应 DOM 节点仍存在。根据页面检查结果,选项并非被接口清空,而是滚动内容离开了可视区域。

预期结果

无论滑动速度多快,picker 都应在手势结束后:

  • 将滚动位置限制在有效范围;
  • 正确执行边界回弹;
  • 吸附到 0 ~ range.length - 1 的有效索引;
  • 不出现 DOM 有选项但界面空白的状态。

补充排查

  • 排除 z-index 遮挡:弹层、“取消”和“完成”均正常显示。
  • 排除 Flutter WebView 独有问题:Chrome 浏览器直接运行 H5 也能复现。
  • 空白状态下 DOM 仍保留选项,接口响应数据和数组均正常。
  • 三个选项同步赋值时暂未复现,异步更新 range 的业务页面可复现。
  • 怀疑 H5 picker-view-columnrange 动态更新后没有完整重算滚动边界,快速滑动时惯性或 spring 回弹未将 translateY 修正回有效范围。

请协助检查 range 动态更新后的 scroller 状态、边界 extent 计算及快速滑动后的回弹/吸附逻辑。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions