uni-index-list需预分组且index为大写字母,中文首字母用Intl.Collator或pinyin-pro转拼音,英文取首单词首字母;索引点击滚动需id匹配、scroll-y固定高;搜索联动须分离显示数据与索引锚点。

uni-app里用 uni-index-list 实现城市字母索引列表
直接用官方组件最省事,但得注意它不是开箱即用——uni-index-list 要求数据必须按 index 字段预分组,且每个分组的 index 值必须是单个大写字母(如 "A"、"B"),不能是 "#" 或中文。常见错误是传入未处理的原始城市数组,结果列表空白或报错 Cannot read property 'length' of undefined。
实操步骤:
- 先对城市数组按首字母分组:用
Array.prototype.reduce()提取每个城市的首字母(推荐用Intl.Collator处理中文拼音,比正则更稳) - 确保每组对象带
index: "A"字段,且组内list是数组(哪怕只有一项) - 把分组结果传给
uni-index-list的list属性,别传错层级 - 注意
uni-index-list在 H5 和小程序表现一致,但 App 端需开启usingComponents且依赖uni_modules/uni-index-list版本 ≥1.0.8
城市名称首字母提取:中文拼音 vs 英文首字符
用户看到的是“北京”“广州”,但排序依据必须是拼音首字母。用 charCodeAt(0) 直接取中文字符 ASCII 值会得到乱码数字(如“北”是 21271),完全不可用。
稳妥做法:
- H5 环境优先用
Intl.Collator:它原生支持拼音排序,无需引入第三方库 - 小程序和 App 端可搭配
pinyin-pro(轻量、无副作用)或chinese-to-pinyin,避免用全量node-pinyin - 英文城市名(如 “New York”)要先
trim().split(" ")[0]取第一个单词,再取首字母大写,否则可能拿到空格或小写 - 特殊字符开头的城市(如 “Örebro”)建议归入
"O"组,用normalize("NFD")去音标后再取首字符
点击索引快速滚动卡顿?检查 scroll-into-view 的 target 格式
索引点击后没跳转或滚动缓慢,大概率是 scroll-into-view 绑定的 id 不匹配。uni-app 的 uni-index-list 内部为每个索引项生成了 id="index-A" 这样的值,但你手动写的 scroll-view + view 结构必须严格对应。
关键点:
-
scroll-view必须设scroll-y且高度固定(不能靠内容撑开) - 每个字母分组的
view标签需带:id="'index-' + item.index",注意拼接方式和大小写 - 触发滚动时传入的
scrollTop值若用querySelector计算,务必等 DOM 渲染完成(用$nextTick包一层) - 真机调试时,iOS 微信浏览器对
scroll-into-view支持不稳定,可降级为scrollTo+ 手动计算 offsetTop
搜索框联动索引列表时,过滤后如何保持字母索引可见
用户输入“深”,期望看到“深圳”在 S 分组下高亮,而不是整个列表只剩一个城市且索引栏消失。这需要两层逻辑分离:显示数据源(过滤后的城市)和索引锚点(所有存在的首字母)。
正确做法:
- 维护两个响应式数据:
filteredCities(当前搜索结果)和allIndexes(原始数据的所有首字母去重数组) - 渲染索引栏时遍历
allIndexes,但每个字母分组内部用filteredCities.filter(c => c.index === letter)渲染内容 - 如果某字母下无匹配城市,该分组仍要渲染(可留空或显示“暂无城市”),否则索引栏会跳动、错位
- 不要在过滤时修改原始分组结构——那会导致索引点击滚动目标丢失
最易被忽略的是:搜索清空后,必须重置 filteredCities 为完整分组数据,而不是简单赋值原始数组,否则分组字段(如 index、list)结构不一致,uni-index-list 会渲染异常。


















