Skip to content

picker ​

从底部弹起的滚动选择器。支持五种选择器,通过mode来区分,分别是普通选择器,多列选择器,时间选择器,日期选择器,省市区选择器,默认是普通选择器。

普通选择器 ​

mode = selector

属性说明

属性名类型默认值说明平台差异说明
rangeArray / Array<Object>[]mode为 selector 或 multiSelector 时,range 有效
range-keyString当 range 是一个 Array<Object> 时,通过 range-key 来指定 Object 中 key 的值作为选择器显示内容
valueNumber0value 的值表示选择了 range 中的第几个(下标从 0 开始)
selector-typeStringauto大屏时UI类型,支持 picker、select、auto,默认在 iPad 以 picker 样式展示而在 PC 以 select 样式展示
disabledBooleanfalse是否禁用快手小程序不支持
@changeEventHandlevalue 改变时触发 change 事件,event.detail =
@cancelEventHandle取消选择或点遮罩层收起 picker 时触发快手小程序不支持
  • picker在各平台的实现是有UI差异的,有的平台如百度、支付宝小程序的Android端是从中间弹出的;有的平台支持循环滚动如百度小程序;有的平台没有取消按钮如App-iOS端。但均不影响功能使用。

多列选择器 ​

mode = multiSelector

平台差异说明

H5微信小程序抖音小程序、飞书小程序小红书小程序快手小程序
√√√√√

属性说明

属性名类型默认值说明
range二维 Array / 二维 Array<Object>[]mode为 selector 或 multiSelector 时,range 有效。二维数组,长度表示多少列,数组的每项表示每列的数据,如[["a","b"], ["c","d"]]
range-keyString当 range 是一个二维 Array<Object> 时,通过 range-key 来指定 Object 中 key 的值作为选择器显示内容
valueArray[]value 每一项的值表示选择了 range 对应项中的第几个(下标从 0 开始)
@changeEventHandlevalue 改变时触发 change 事件,event.detail =
@columnchangeEventHandle某一列的值改变时触发 columnchange 事件,event.detail = {column: column, value: value},column 的值表示改变了第几列(下标从0开始),value 的值表示变更值的下标
@cancelEventHandle取消选择时触发(快手小程序不支持)
disabledBooleanfalse是否禁用(快手小程序不支持)

bug & tips

  • 由于 JavaScript 的限制 vue 不能观测如下方式设置 value:this.value[0] = 0 (vue 注意事项),解决方式参考:hello-uniapp 示例
  • 微信开发工具的pc模拟器有可能出现拖动数据错乱,使用真机正常

时间选择器 ​

mode = time

平台差异说明

H5微信小程序抖音小程序、飞书小程序小红书小程序快手小程序
√√√√x
  • 时间选择在App端调用的是os的原生时间选择控件,在不同平台有不同的ui表现

属性说明

属性名类型默认值说明平台差异说明
valueString表示选中的时间,格式为"hh:mm"
startString表示有效时间范围的开始,字符串格式为"hh:mm"App 不支持
endString表示有效时间范围的结束,字符串格式为"hh:mm"App 不支持
@changeEventHandlevalue 改变时触发 change 事件,event.detail =
@cancelEventHandle取消选择时触发
disabledBooleanfalse是否禁用 

日期选择器 ​

mode = date

平台差异说明

H5微信小程序抖音小程序、飞书小程序小红书小程序快手小程序
√√√√x

日期选择默认在App端和H5端(PC版Chrome以及PC版FireFox)调用的是os的原生日期选择控件,在不同平台有不同的ui表现,当配置fields参数后使用统一的展示方式。

属性说明

属性名类型默认值说明平台差异说明
valueString0表示选中的日期,格式为"YYYY-MM-DD"
startString表示有效日期范围的开始,字符串格式为"YYYY-MM-DD"
endString表示有效日期范围的结束,字符串格式为"YYYY-MM-DD"
fieldsStringday有效值 year、month、day,表示选择器的粒度,默认为 day,App 端未配置此项时使用系统 UIH5、微信小程序、抖音小程序、飞书小程序
@changeEventHandlevalue 改变时触发 change 事件,event.detail =
@cancelEventHandle取消选择时触发
disabledBooleanfalse是否禁用 

fields 有效值

值说明
year选择器粒度为年
month选择器粒度为月份
day选择器粒度为天

省市区选择器 ​

mode = region

平台差异说明

H5微信小程序抖音小程序、飞书小程序小红书小程序快手小程序
√√√√x
  • 小程序平台在引擎层面内置了省市区数据。但省市区包含大量数据,占用体积,并非所有应用都需要,且很多城市数据有自维护需求,所以在H5平台没有在前端内置这些数据。可以基于多列picker或picker-view,自行填充城市数据。插件市场有较多类似插件,详见。注意基于多列picker方式的地区选择不能运行在支付宝小程序上,只有基于picker-view的可以全端运行。尤其推荐插件uni-data-picker,自带省市区的联网数据,自带懒加载。
属性名类型默认值说明
valueArray[]表示选中的省市区,默认选中每一列的第一个值
custom-itemString可为每一列的顶部添加一个自定义的项
@changeEventHandlevalue 改变时触发 change 事件,event.detail =
@cancelEventHandle取消选择时触发(快手小程序不支持)
disabledBooleanfalse是否禁用(快手小程序不支持)

示例 查看演示

以下示例代码,来自于hello uni-app项目,推荐使用HBuilderX,新建uni-app项目,选择hello uni-app模板,可直接体验完整示例。

vue
<template>
  <view>
    <view class="uni-title uni-common-pl">地区选择器</view>
    <view class="uni-list">
      <view class="uni-list-cell">
        <view class="uni-list-cell-left">
          当前选择
        </view>
        <view class="uni-list-cell-db">
          <picker @change="bindPickerChange" :value="index" :range="array">
            <view class="uni-input">{{array[index]}}</view>
          </picker>
        </view>
      </view>
    </view>

    <view class="uni-title uni-common-pl">时间选择器</view>
    <view class="uni-list">
      <view class="uni-list-cell">
        <view class="uni-list-cell-left">
          当前选择
        </view>
        <view class="uni-list-cell-db">
          <picker
            mode="time"
            :value="time"
            start="09:01"
            end="21:01"
            @change="bindTimeChange"
          >
            <view class="uni-input">{{time}}</view>
          </picker>
        </view>
      </view>
    </view>

    <view class="uni-title uni-common-pl">日期选择器</view>
    <view class="uni-list">
      <view class="uni-list-cell">
        <view class="uni-list-cell-left">
          当前选择
        </view>
        <view class="uni-list-cell-db">
          <picker
            mode="date"
            :value="date"
            :start="startDate"
            :end="endDate"
            @change="bindDateChange"
          >
            <view class="uni-input">{{date}}</view>
          </picker>
        </view>
      </view>
    </view>
  </view>
</template>
<template>
  <view>
    <view class="uni-title uni-common-pl">地区选择器</view>
    <view class="uni-list">
      <view class="uni-list-cell">
        <view class="uni-list-cell-left">
          当前选择
        </view>
        <view class="uni-list-cell-db">
          <picker @change="bindPickerChange" :value="index" :range="array">
            <view class="uni-input">{{array[index]}}</view>
          </picker>
        </view>
      </view>
    </view>

    <view class="uni-title uni-common-pl">时间选择器</view>
    <view class="uni-list">
      <view class="uni-list-cell">
        <view class="uni-list-cell-left">
          当前选择
        </view>
        <view class="uni-list-cell-db">
          <picker
            mode="time"
            :value="time"
            start="09:01"
            end="21:01"
            @change="bindTimeChange"
          >
            <view class="uni-input">{{time}}</view>
          </picker>
        </view>
      </view>
    </view>

    <view class="uni-title uni-common-pl">日期选择器</view>
    <view class="uni-list">
      <view class="uni-list-cell">
        <view class="uni-list-cell-left">
          当前选择
        </view>
        <view class="uni-list-cell-db">
          <picker
            mode="date"
            :value="date"
            :start="startDate"
            :end="endDate"
            @change="bindDateChange"
          >
            <view class="uni-input">{{date}}</view>
          </picker>
        </view>
      </view>
    </view>
  </view>
</template>
js
<script>
export default {
  data() {
    const currentDate = this.getDate({
      format: true,
    });
    return {
      title: 'picker',
      array: ['中国', '美国', '巴西', '日本'],
      index: 0,
      date: currentDate,
      time: '12:01',
    };
  },
  computed: {
    startDate() {
      return this.getDate('start');
    },
    endDate() {
      return this.getDate('end');
    },
  },
  methods: {
    bindPickerChange: function(e) {
      console.log('picker发送选择改变,携带值为', e.detail.value);
      this.index = e.detail.value;
    },
    bindDateChange: function(e) {
      this.date = e.detail.value;
    },
    bindTimeChange: function(e) {
      this.time = e.detail.value;
    },
    getDate(type) {
      const date = new Date();
      let year = date.getFullYear();
      let month = date.getMonth() + 1;
      let day = date.getDate();

      if (type === 'start') {
        year = year - 60;
      } else if (type === 'end') {
        year = year + 2;
      }
      month = month > 9 ? month : '0' + month;
      day = day > 9 ? day : '0' + day;
      return `${year}-${month}-${day}`;
    }
  }
};
</script>
<script>
export default {
  data() {
    const currentDate = this.getDate({
      format: true,
    });
    return {
      title: 'picker',
      array: ['中国', '美国', '巴西', '日本'],
      index: 0,
      date: currentDate,
      time: '12:01',
    };
  },
  computed: {
    startDate() {
      return this.getDate('start');
    },
    endDate() {
      return this.getDate('end');
    },
  },
  methods: {
    bindPickerChange: function(e) {
      console.log('picker发送选择改变,携带值为', e.detail.value);
      this.index = e.detail.value;
    },
    bindDateChange: function(e) {
      this.date = e.detail.value;
    },
    bindTimeChange: function(e) {
      this.time = e.detail.value;
    },
    getDate(type) {
      const date = new Date();
      let year = date.getFullYear();
      let month = date.getMonth() + 1;
      let day = date.getDate();

      if (type === 'start') {
        year = year - 60;
      } else if (type === 'end') {
        year = year + 2;
      }
      month = month > 9 ? month : '0' + month;
      day = day > 9 ? day : '0' + day;
      return `${year}-${month}-${day}`;
    }
  }
};
</script>

示例代码说明:以上示例代码从hello uni-app示例中复制,涉及的css样式在hello uni-app的app.vue和uni.css中

预览H5效果:使用浏览器的手机模式访问

注意

  • 在picker内容还在滚动时或滚动回弹动画还未结束时,点确定关闭弹出的picker,数据无法及时更新。需等待一下,或手动触停滚动再点确定。所有平台均如此

扩展

  • qin ui 提供了增强版 <uni-data-picker> 组件,详见
  • 该组件优势如下:
    • 符合 datacom 规范,只需传入 data ,就可以自动生成界面
    • 符合 qin-forms ,表单校验规范
    • 突破多列picker的3列限制,可以承载更多列数据
    • 选择区域面积更高更大
    • 支持多列数据分级加载,比如省市区选择,先选择省,然后动态联网加载该省的市。