dcloudio / dcloudio/uni-app

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

Open
#6,044 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
41.6k
Forks
3.7k
Avg merge
7h 6m
Merged PRs (30d)
6

Description

## 问题描述

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

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

空白时:

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

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

## 环境

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

## 最小结构

```vue




{{ currentIndex !== null && options[currentIndex]
? options[currentIndex].typeName
: '请选择' }}


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)
}
}
}

```

## 复现步骤

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-column` 在 `range` 动态更新后没有完整重算滚动边界,快速滑动时惯性或 spring 回弹未将 `translateY` 修正回有效范围。

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

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.