u-picker 必须全局注册uView,否则H5和小程序报“Unknown custom element”,App端静默失败;需完成main.js引入、uni.scss和App.vue样式导入、easycom配置;columns格式依单列/多列严格区分;不支持mode属性,时间日期须用原生picker;v-model仅绑定显示值,需ref配合@confirm获取真实值;show需手动控制显隐。

u-picker 组件必须先完成 uView 全局注册
没注册就直接用 <u-picker>,H5 和小程序会报“Unknown custom element”错误,App 端可能静默失败但不弹出选择器。注册不是可选项,是硬性前置条件。
关键三步缺一不可:
- 在
main.js中import uView from "uview-ui"并调用Vue.use(uView) - 在项目根目录的
uni.scss中引入@import 'uview-ui/theme.scss' - 在
App.vue的<style lang="scss">第一行加@import "uview-ui/index.scss"
如果使用了 easycom,还需在 pages.json 的 "easycom" 字段里配 "u-*": "uview-ui/components/u-*/u-*.vue" ——否则组件不会自动按需导入,v-model 或 @confirm 事件可能不响应。
单列/多列数据结构写法差异大,别混用
columns 是核心参数,但格式取决于你用的是单列还是多列模式。写错会导致空白、报错或滚动卡死。
- 单列:传一维数组,如
columns: ["苹果", "香蕉", "橙子"] - 多列(并列):传二维数组,每项是独立列,如
columns: [["男", "女"], ["18-25", "26-35", "36+"]] - 多列联动:仍是二维数组,但需配合
@change里调用this.$refs.uPicker.setColumnValues()动态更新后续列;第一列选“中国”,第二列才加载“北京/上海/广州”
注意:uView 的 columns 不接受对象数组(比如 [{label: "A", value: "a"}]),那是原生 <picker> 的 range 写法,混用会渲染失败。
时间/日期选择必须用原生 picker,u-picker 不支持 mode 属性
这是最容易踩的坑:<u-picker mode="time"> 是无效的,u-picker 没有 mode 这个 prop。它只做内容滚动选择,不内置时间/日期逻辑。
正确做法分两路:
- 要时间或日期选择 → 老老实实用 uni-app 原生
<picker mode="time">或<picker mode="date">,配合:value和@change处理 - 要带自定义 UI 的时间选择(比如小时/分钟分开列、加 AM/PM)→ 用
u-picker手动构造columns,例如[["00","01",...,"23"], ["00","05","10",...,"55"]],再自己拼接成"14:30"
强行给 u-picker 加 mode 不仅无效,还会让 IDE 报类型警告,编译时也可能被 Vue 的 props 校验拦截。
确认回调和值绑定必须用 ref + v-model 组合
u-picker 没有内置的双向绑定机制,v-model 只能绑定显示值,真正拿到选中项得靠 @confirm 回调里的 e.detail.value 或 e.detail.values(多列时)。
- 单列:用
@confirm="val => selected = val.detail.value",val.detail.value是字符串或数字(取决于columns类型) - 多列:
val.detail.values是数组,如["中国", "上海"];若需对应 code,得提前建好映射表,不能依赖组件自动转换 - 想在点击确定前预览选中项?监听
@change,但注意它触发频繁,且 H5 和小程序行为不一致(H5 滚动中就触发,小程序等停稳才触发)
最后提醒一句:u-picker 的 show 是受控属性,别忘了在 @confirm 或 @cancel 后手动设回 false,否则弹窗关不掉——这个细节在真机调试时才暴露,模拟器里常被忽略。


















