uni-indexed-list 实现城市索引需配合 uni-indexed-list-item(带 index 属性)、预处理数据为按首字母分组的数组,并用 pinyin-pro 转拼音取大写首字母;showselect 控制索引栏显隐,滑动定位需正确绑定 id 并在 $nexttick 中执行 pagescrollto。

uni-app 中用 uni-indexed-list 实现城市索引列表要配什么?
直接上结论:uni-indexed-list 是 uni-app 官方组件,但默认不带字母索引栏(右侧 A-Z 滑动导航),必须配合 uni-indexed-list-item + index 属性手动分组,且数据需预处理成带 index 字段的数组结构。
常见错误是把原始城市数组直接传给 list,结果索引栏空白、点击无响应、滑动定位失效——根本原因是没按组件要求做「首字母归类」。
- 每个
uni-indexed-list-item必须有index属性,值为单个大写字母(如"B"),不能是中文或小写 - 原始城市数据需先用
pinyin库(如pinyin-pro)转拼音,再取首字母并大写,最后按字母分组聚合 -
uni-indexed-list的showSelect属性控制是否显示右侧索引栏,不设为true就看不见 A-Z - H5 端支持原生滚动,App 和小程序端依赖
scroll-top模拟定位,需确保每个index组的id唯一且可被uni.createSelectorQuery()获取
为什么用 pinyin-pro 而不是 js-pinyin?
js-pinyin 在 uni-app 的 App 端常报 Cannot read property 'match' of undefined,本质是它依赖 document 或正则某些非标准行为;pinyin-pro 是纯函数式、无 DOM 依赖、支持 Tree Shaking,体积更小(gzip 后约 12KB),且对多音字、生僻字兼容更好。
实操建议:
- 安装:
npm install pinyin-pro --save - 使用时只引入需要的方法:
import { getPinyin } from 'pinyin-pro' - 取首字母别用
.charAt(0),改用.slice(0, 1).toUpperCase()避免中文字符截断乱码 - 遇到「乌鲁木齐」「拉萨」等藏/维语地名,
pinyin-pro默认返回空字符串,需 fallback 到汉字 Unicode 首字节:例如city.charCodeAt(0) > 128 ? 'A' : getFirstLetter(city)
uni-indexed-list 滑动定位不准或跳转失败怎么调?
典型现象:点击右侧 "S",列表滚动到一半就停住,或者直接卡在顶部。这不是组件 bug,而是 scroll 目标元素未正确绑定或渲染时机不对。
关键点:
- 每个
uni-indexed-list-item必须加:id="'index-' + item.index",且item.index与索引栏点击的字母严格一致(大小写、去重) - 不要在
v-for外层套scroll-view,uni-indexed-list内部已封装滚动逻辑,额外包裹会破坏scrollTop计算 - App 端需在
$nextTick后执行滚动,否则节点尚未挂载:handleIndexTap(index) { this.$nextTick(() => { const query = uni.createSelectorQuery().in(this); query.select(`#index-${index}`).boundingClientRect(); query.exec(res => { if (res[0]) uni.pageScrollTo({ scrollTop: res[0].top - 100 }); }); }); } - 小程序真机调试时,
pageScrollTo可能因 WXML 渲染延迟失败,建议加setTimeout50ms 重试一次
如何让城市列表默认展开「热门城市」并置顶?
官方 uni-indexed-list 不支持插槽插入非索引项,所以「北京、上海、广州、深圳」这类热门城市不能硬塞进某个 index 分组里——否则会出现在「B」「S」下面,逻辑混乱。
解决方案是结构分离:
- 用一个独立的
view区域放热门城市,flex横向滚动,上面加「热门」标题 - 下方才是
uni-indexed-list,数据从「A」开始,确保第一个index是"A" - 热门城市数组单独维护,不参与拼音排序;如果也要支持点击跳转,给每个城市加
data-city属性,用uni.pageScrollTo手动滚动到对应id(如#city-beijing) - 注意:热门区域高度会影响
uni-indexed-list的scrollTop计算,滚动前需减去该区域高度(可用getRect动态获取)
最易忽略的是:热门城市和索引列表之间要有明显视觉分隔(比如 border-top 或留白),否则用户会误以为它们属于同一套索引体系。











