cube-ui Picker 选择器组件完全指南:从单列到多列、别名配置与动态更新实战

发布时间:2026/9/25 3:12:42

cube-ui Picker 选择器组件完全指南:从单列到多列、别名配置与动态更新实战 前端UI组件移动开发【免费下载链接】cube-ui:large_orange_diamond: A fantastic mobile ui lib implement by Vue项目地址https://gitcode.com/gh_mirrors/cu/cube-ui点击查看免费下载Picker 是 cube-ui 中基于 create-api 实现的移动端选择器组件通过二维数组data即可驱动单列或多列滚轮联动选择广泛用于表单选项、筛选条件和级联场景。本文以 官方文档 为主线结合组件源码与单元测试完整讲解其配置项、事件、实例方法及底层滚动实现原理帮助你在项目中快速落地可复用的选择器。组件概述与前置知识Picker组件本质上是一个由 BetterScroll 驱动的滚轮选择器每一列数据渲染为一个独立的滚动轮用户滚动到目标项后点击「确定」完成选择。组件本身不直接以模板标签方式挂在页面上而是通过this.$createPicker(options)命令式创建并调用.show()展示因此在继续阅读之前建议先了解 create-api 的使用方式。从源码看Picker 的注册链路为模块入口 src/modules/picker/index.js 调用Vue.use(Picker)时既注册全局组件cube-picker又通过 src/modules/picker/api.js 的createAPI(Vue, Picker, [select, value-change, cancel, change])注入$createPicker实例方法四个事件名即组件对外暴露的事件白名单import createAPI from ../../common/helpers/create-api import { tip } from ../../common/helpers/debug export default function addPicker (Vue, Picker) { const pickerAPI createAPI(Vue, Picker, [select, value-change, cancel, change]) pickerAPI.before((data, renderFn, single) { if (single) { tip(Picker component can not be a singleton.) } }) }值得注意的是Picker 不是单例组件每次$createPicker都会创建一个独立实例若传入single true会在开发环境通过 src/common/helpers/debug.js 输出一条[Cube tip]: Picker component can not be a singleton.警告。数据驱动data 二维数组定义选择器选项的核心属性是data。它是一个二维数组第一维度决定选择器有多少列滚轮第二维度决定每一列有哪些选项。每个选项对象默认包含text展示文案与value对应值两个字段见 src/common/mixins/basic-picker.js 中的默认键定义const DEFAULT_KEYS { value: value, text: text, order: order }单列选择器传入data: [column1]即生成一个单列滚轮。以下是官方文档给出的完整示例点击按钮弹起 Picker确认后通过 Dialog 展示所选内容cube-button clickshowPickerPicker/cube-buttonconst column1 [{ text: 剧毒, value: 剧毒}, { text: 蚂蚁, value: 蚂蚁 }, { text: 幽鬼, value: 幽鬼 }] export default { methods: { showPicker() { if (!this.picker) { this.picker this.$createPicker({ title: Picker, data: [column1], onSelect: this.selectHandle, onCancel: this.cancelHandle }) } this.picker.show() }, selectHandle(selectedVal, selectedIndex, selectedText) { this.$createDialog({ type: warn, content: Selected Item: br/ - value: ${selectedVal.join(, )} br/ - index: ${selectedIndex.join(, )} br/ - text: ${selectedText.join( )}, icon: cubeic-alert }).show() }, cancelHandle() { this.$createToast({ type: correct, txt: Picker canceled, time: 1000 }).show() } } }示例中的column1在实际仓库中预置了更丰富的选项如「主宰」「卡尔」「宙斯」等见 example/data/picker.js可直接引入用于快速调试。多列选择器当data第一维度传入多列数组时Picker 会自动渲染为多列联动滚轮。例如三列选择器cube-button clickshowMutiPickerMulti-column Picker/cube-buttonconst column1 [{ text: 剧毒, value: 剧毒}, { text: 蚂蚁, value: 蚂蚁 }, { text: 幽鬼, value: 幽鬼 }] const column2 [{ text: 输出, value: 输出 }, { text: 控制, value: 控制 }, { text: 核心, value: 核心}, { text: 爆发, value: 爆发 }] const column3 [{ text: 梅肯, value: 梅肯}, { text: 秘法鞋, value: 秘法鞋 }, { text: 假腿, value: 假腿 }, { text: 飞鞋, value: 飞鞋 }] export default { methods: { showMutiPicker() { if (!this.mutiPicker) { this.mutiPicker this.$createPicker({ title: Multi-column Picker, data: [column1, column2, column3], onSelect: this.selectHandle, onCancel: this.cancelHandle }) } this.mutiPicker.show() }, selectHandle(selectedVal, selectedIndex, selectedText) { this.$createDialog({ type: warn, content: Selected Item: br/ - value: ${selectedVal.join(, )} br/ - index: ${selectedIndex.join(, )} br/ - text: ${selectedText.join( )}, icon: cubeic-alert }).show() }, cancelHandle() { this.$createToast({ type: correct, txt: Picker canceled, time: 1000 }).show() } } }每个选中回调中的三个参数均为数组数组长度与列数一一对应selectedVal是每列选中项的valueselectedIndex是每列选中项的索引selectedText是每列选中项的文案。选项的子属性别名 alias当数据源字段不是默认的value/text时例如后端返回id/name无需提前做数据映射直接通过alias配置键名别名即可cube-button clickshowAliasPickerUse Alias/cube-buttonexport default { methods: { showAliasPicker() { if (!this.aliasPicker) { this.aliasPicker this.$createPicker({ title: Use Alias, data: [[{ id: 1, name: A }, { id: 2, name: B }, { id: 3, name: C }]], alias: { value: id, text: name }, onSelect: this.selectHandle, onCancel: this.cancelHandle }) } this.aliasPicker.show() }, // selectHandle / cancelHandle 同上例 } }底层实现在 src/common/mixins/basic-picker.js 中通过计算属性解析computed: { valueKey() { return this.alias.value || DEFAULT_KEYS.value }, textKey() { return this.alias.text || DEFAULT_KEYS.text }, orderKey() { return DEFAULT_KEYS.order } }即alias.value覆盖取值字段、alias.text覆盖文案字段未配置时回退到默认的value/text另外还有一个固定的order键用于多列场景下控制列的展示顺序模板中通过_getFlexOrder读取item[orderKey]作为 flex order见 src/components/picker/picker.vue。对应的别名渲染行为在单元测试 test/unit/specs/picker.spec.js 中有验证当alias: { value: id, text: name }时第二项展示文案应为B。动态更新实例方法 $updateProps 与 setData$updateProps 更新配置创建后的 Picker 实例可以通过$updateProps动态修改任意 props。官方文档示例演示了 1 秒后将单列 Picker 更新为三列并改变选中项cube-button clickshowUpdatePropsPickerUse $updateProps/cube-buttonconst column1 [{ text: 剧毒, value: 剧毒}, { text: 蚂蚁, value: 蚂蚁 }, { text: 幽鬼, value: 幽鬼 }] const column2 [{ text: 输出, value: 输出 }, { text: 控制, value: 控制 }, { text: 核心, value: 核心}, { text: 爆发, value: 爆发 }] const column3 [{ text: 梅肯, value: 梅肯}, { text: 秘法鞋, value: 秘法鞋 }, { text: 假腿, value: 假腿 }, { text: 飞鞋, value: 飞鞋 }] export default { methods: { showUpdatePropsPicker() { if (!this.updatePropsPicker) { this.updatePropsPicker this.$createPicker({ title: Use $updateProps, data: [column1], selectedIndex: [0], onSelect: this.selectHandle, onCancel: this.cancelHandle }) } this.updatePropsPicker.show() setTimeout(() { this.updatePropsPicker.$updateProps({ title: Updated, data: [column1, column2, column3], selectedIndex: [1, 2, 3] }) }, 1000) }, // selectHandle / cancelHandle 同上 } }$updateProps是 create-api 为实例注入的通用方法。当data或selectedIndex变化时组件内部通过 basic-picker.js 中合并的mergewatcher 自动调用setData(newVal[0], newVal[1])完成滚轮重建与定位。setData 方法setData(data, selectedIndex)用于设置可选项与选中索引两个参数均为数组。其实现src/components/picker/picker.vue会区分当前是否可见不可见时仅更新内部_indexes与finalData并标记dirty true待下次show()时再创建滚轮可见时立即在$nextTick中重建每列滚轮并wheelTo定位到目标索引同时销毁多余的滚轮_destroyExtraWheels。setData(data, selectedIndex) { this._indexes selectedIndex ? [...selectedIndex] : [] this.finalData data.slice() if (this.isVisible) { this.$nextTick(() { const wheelWrapper this.$refs.wheelWrapper this.finalData.forEach((item, i) { this._createWheel(wheelWrapper, i) this.wheels[i].wheelTo(this._indexes[i]) }) this._destroyExtraWheels() }) } else { this.dirty true } }在 example/pages/picker.vue 中还展示了setData的典型用法创建时不传data展示前用setData([column1, column2, column3], [1, 2, 3])动态填充三列数据。单元测试 test/unit/specs/picker.spec.js 分别覆盖了「隐藏时 setData」「可见时 setData」两种分支确认最终confirm()后_indexes与_values均与传入数据一致。Props 配置总览| 参数 | 说明 | 类型 | 默认值 | 示例 | | - | - | - | - | - | | data | 传入 picker 数据数组的长度决定了 picker 的列数 | Array | [] | - | | selectedIndex | 被选中的索引值拉起 picker 后显示这个索引值对应的内容 | Array | [] | [1] | | title | 标题 | String | | - | | subtitle1.8.1| 副标题 | String | | - | | cancelTxt | 取消按钮文案 | String | 取消 | - | | confirmTxt | 确定按钮文案 | String | 确定 | - | | swipeTime | 快速滑动 picker 滚轮时惯性滚动动画的时长单位ms | Number | 2500 | - | | alias | 配置value和text的别名 | Object | {} | { value: id, text: name} | | visible1.8.1| 显示状态是否可见。v-model绑定值 | Boolean | true/false | false | | maskClosable1.9.6| 点击蒙层是否隐藏 | Boolean | true/false | true | | zIndex1.9.6| 样式 z-index 的值 | Number | 100 | - |data 子配置项| 参数 | 说明 | 类型 | 默认值 | 示例 | | - | - | - | - | - | | text | picker 每一列展示的文案 | String/Number | - | - | | value | picker 每一列展示的每项文案对应的值 | String/Number/Boolean | - | - |配置项的源码归属与补充说明data / selectedIndex / alias定义在 src/common/mixins/basic-picker.js其中alias.value影响取值字段、alias.text影响文案字段title / subtitle / cancelTxt / confirmTxt / swipeTime / maskClosable定义在 src/common/mixins/picker.js。cancelTxt与confirmTxt的默认值并非硬编码字符串而是走国际化未配置时回退到this.$t(cancel)与this.$t(ok)在 src/locale/lang/zh-CN.js 中对应「取消」与「确定」因此文档表格中的默认值「取消」「确定」实际来自 locale 语言包swipeTime直接透传给 BetterScroll 的swipeTime配置控制快速滑动后的惯性动画时长毫秒见 src/components/picker/picker.vue 中_createWheel的swipeTime: this.swipeTimevisible由 src/common/mixins/visibility.js 提供v-model双向绑定支持model: { prop: visible, event: toggle }意味着你也可以用v-modelvisible指令式控制显示隐藏zIndex / maskClosablezIndex 默认 100来自 src/common/mixins/popup.js会作用于内部cube-popup的层级maskClosable在 picker.js mixin 中默认值为true点击蒙层时执行cancel()并触发cancel事件见 picker.vue 的maskClick。事件| 事件名 | 说明 | 参数1 | 参数2 | 参数3 | | - | - | - | - | - | | select | 点击确认按钮触发此事件 | selectedVal: 当前选中项每一列的值Array 类型 | selectedIndex: 当前选中项每一列的索引Array 类型 | selectedText: 当前选中项每一列的文案Array 类型 | | change | 滚轴滚动后触发此事件 | index: 当前滚动列次序Number 类型 | selectedIndex: 当前列选中项的索引Number 类型 | | value-change | 所确认的值变化时触发此事件 | selectedVal: 当前确认项每一列的值Array 类型 | selectedIndex: 当前确认项每一列的索引Array 类型 | selectedText: 当前选中项每一列的文案Array 类型 | | cancel | 点击取消按钮触发此事件 | - | - | - |事件触发时机与实现细节在 src/components/picker/picker.vue 中select点击「确定」按钮触发confirm()组件遍历所有滚轮取出每列索引、值与文案统一$emit(select, this._values, this._indexes, pickerSelectedText)value-change在confirm()内部若任一列的值相比上一次确认发生了变化含列数变化的情况则额外触发$emit(value-change, ...)因此它是「确认后值确实改变」时的补充事件适合做表单脏检查或联动回调change由 BetterScroll 的scrollEnd事件驱动在_createWheel中注册wheel.on(scrollEnd, ...)滚动停止即触发可用于在用户滚动过程中实时感知某列当前停留在哪一项cancel点击「取消」按钮或当maskClosable为 true 时点击蒙层触发$emit(cancel)。需要注意的是confirm()前会执行_canConfirm()检查当pending为 true 或任一滚轮仍处于惯性过渡中wheel.isInTransition时本次确认会被忽略从而避免在动画未结束时误提交结果。上述四个事件的完整触发链路均有单元测试覆盖见 test/unit/specs/picker.spec.js 中「should trigger events」用例分别点击取消与确认按钮断言各 spy 的调用次数。实例方法| 方法名 | 说明 | 参数1 | 参数2 | | - | - | - | - | | setData | 设置 picker 可选项 | picker 每列可选项的文案和值Array 类型 | picker 每列选中的索引Array 类型 | | show | 显示 | - | - | | hide | 隐藏 | - | - |show()首次调用时在$nextTick中为每一列创建 BetterScroll 滚轮实例并通过wheelTo(this._indexes[i])定位到初始选中项重复调用仅重置各滚轮状态enable()wheelTohide()将isVisible置为 false 并disable()所有滚轮阻止底层滚动穿透setData(data, selectedIndex)见上文「动态更新」一节。组件销毁时beforeDestroy会逐一wheel.destroy()释放所有 BetterScroll 实例避免内存泄漏这也是推荐「创建一次实例、多次 show/hide 复用」而非频繁重建的底层原因。底层原理BetterScroll 滚轮机制Picker 的每一列都是一个独立的 BetterScroll 实例创建逻辑集中在_createWheelsrc/components/picker/picker.vue_createWheel(wheelWrapper, i) { if (!this.wheels[i]) { const wheel this.wheels[i] new BScroll(wheelWrapper.children[i], { wheel: { selectedIndex: this._indexes[i] || 0, wheelWrapperClass: cube-picker-wheel-scroll, wheelItemClass: cube-picker-wheel-item }, swipeTime: this.swipeTime, observeDOM: false, useTransition: USE_TRANSITION }) wheel.on(scrollEnd, () { this.$emit(EVENT_CHANGE, i, this._getSelectIndex(wheel)) }) } else { this.wheels[i].refresh() } return this.wheels[i] }关键点wheel.selectedIndex指定初始选中项索引swipeTime控制惯性动画时长observeDOM: false表示不监听 DOM 变化、依赖组件自身在数据变更时主动refresh()USE_TRANSITION来自 src/common/bscroll/constants.js决定是否使用 CSS transition当其为 false 时_getSelectIndex会退化用滚轮y位移与itemHeight手动计算选中索引以规避 BetterScroll 在useTransition: false下getSelectedIndex不准确的问题滚轮渲染依赖固定的样式约定ul.cube-picker-wheel-scroll与li.cube-picker-wheel-item对应 picker.vue 模板中带注释的类名两者必须保持与 BetterScroll 的wheelWrapperClass/wheelItemClass配置一致否则滚轮无法正常滚动定位。实战与 Select、CascadePicker 的定位差异Picker 是最基础的滚轮选择器只负责「展示数据 滚动选择 回传结果」。若需要字段表单控件可使用 Select 选择器文档 对应的组件其内部同样基于 Picker 实现但面向表单字段使用多级联动省市区等可使用 CascadePicker 级联选择器文档它继承并扩展了 Picker 的数据组织与联动逻辑时间选择可使用 DatePicker 日期选择器文档 与 TimePicker 时间选择器文档。理解 Picker 的data二维结构、alias键名映射、select/value-change/change/cancel四个事件与setData/$updateProps动态能力是掌握上层衍生组件级联、日期、时间、字段选择的基础。快速接入步骤安装注册通过Vue.use(Picker)引入 src/modules/picker/index.js 导出的模块按需构建时对应lib/picker目录注册后全局可用cube-picker组件与this.$createPicker实例方法准备数据按「列 → 选项」组织二维数组选项对象默认含text/value或通过alias指定自定义字段名创建实例在事件回调中调用this.$createPicker({ title, data, selectedIndex, onSelect, onCancel })并.show()即可拉起底部弹出式滚轮选择器响应结果在onSelect中通过selectedVal/selectedIndex/selectedText三个并行数组消费选择结果动态更新可选需要变更数据或选中态时调用实例的setData(data, selectedIndex)或$updateProps({...})。完整的可运行示例参考 example/pages/picker.vue 与配套数据 example/data/picker.js单元测试 test/unit/specs/picker.spec.js 则提供了对渲染、事件、别名、动态 setData 等行为的最小验证范本。赞分享前端UI组件移动开发【免费下载链接】cube-ui:large_orange_diamond: A fantastic mobile ui lib implement by Vue项目地址https://gitcode.com/gh_mirrors/cu/cube-ui点击查看免费下载相关推荐拆解 legacy-rocm-build 的发布流水线拆解 legacy rocm build 的发布流水线 legacy rocm build 看起来只是个 ROCm 文档仓库但它其实是整个 ROCm 软件栈的开发工具高性能计算文档Vant Weapp Picker 选择器组件完全指南单列、多列级联与实例方法实战Vant Weapp Picker 选择器组件完全指南单列、多列级联与实例方法实战 Picker 是 Vant Weapp 小程序组件库中用于多选项集合选择前端小程序UI组件移动开发amis Radios 单选框组件完全指南JSON 配置、选项来源与多列布局实战amis Radios 单选框组件完全指南JSON 配置、选项来源与多列布局实战 导读 Radios 是 amis 前端低代码框架中最基础也最常用的单选表单项前端低代码UI组件上一篇Sunshine 游戏串流完整教程安装、Moonlight 配对与参数调优一步到位下一篇Apache Calcite企业级SQL优化引擎5大核心架构模式实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/25 3:12:42

技术博主暂停更新公告写作指南:从决策到复更的完整流程

如果你的项目日志停在了三个月前,仓库里还挂着几笔没合并的提交,私信里攒了二十几条"博主你还活着吗"——恭喜你,你在某个深夜打开编辑器,想写一篇暂停更新公告。写这篇东西之前,我在后台对着空白文档坐了半…

2026/9/25 3:57:44

网上订餐系统毕设实战:Spring Boot+Vue全栈开发与答辩指南

做毕设选这个题目,我先说个结论:网上订餐系统这个选题,放在Spring Boot Vue这套组合里,是当前性价比最高的方向之一。原因很简单,它不属于那种冷门小众的偏题,业务流程完整、角色划分清晰、技术栈主流&…

2026/9/25 3:57:44

高校选课系统开题答辩全攻略:从选题到防坑指南

开题答辩这件事,很多同学把它当成“走过场”——PPT念一遍,评委随便问两句,半小时就结束了。但等你真正站在讲台上,面对三位评委老师齐齐看向你的目光,才发现那些“随便问”的问题,每一条都踩在你的项目软肋…

2026/9/25 3:57:44

基于Spring Boot+Vue的数码产品对比平台:全栈开发与数据建模实战

二手手机怎么选才不会踩坑?笔记本标压和低压处理器到底差多少?这些问题的答案,本质上都指向同一个东西:可靠的参数数据与直观的横向对比。我最近用 Java、Spring Boot 和 Vue 落地了一个数码产品对比平台,正好把全栈开…

2026/9/25 3:57:44

Neo4j 5.26 Windows实战:安装配置、CSV导入与多跳查询

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 3:57:44

零代码API服务:从SQL到HTTP接口的原理、落地与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 20:24:47

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/23 12:06:55

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/25 0:02:35

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:02:35

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:02:35

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/22 16:34:32

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/22 20:01:30

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/22 13:25:41

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑