Skip to content

Picker 选择器组件

此选择器用于单列、多列、多列联动的选择场景。

📌平台差异说明

APP(vue)H5微信小程序支付宝小程序

⚠️注意事项

注意事项

  • hasInputtrue 时,通过点击输入框打开选择器,无需设置 show 属性
  • modelValue 在单列模式下为字符串或数字,多列模式下为数组
  • 多列联动需要在 change 事件中调用 setColumnValues 方法更新后续列数据
  • columns 参数支持一维数组(单列)或二维数组(多列)
  • popupMode 目前仅支持 bottomtop 两种模式

🏯基本使用示例

基础使用(单列模式)

html
<template>
    <hy-picker :show="show" :columns="columns" @confirm="onConfirm"></hy-picker>
    <hy-cell clickable @click="show = true">
        <hy-cell-item title="打开选择器" :value="value"></hy-cell-item>
    </hy-cell>
</template>

<script setup>
    import { ref, reactive } from 'vue'

    const show = ref(false)
    const value = ref('')
    const columns = reactive([['中国', '美国', '日本', '韩国']])

    const onConfirm = (e) => {
        value.value = e.value.join('')
        show.value = false
    }
</script>

通过输入框打开

html
<template>
    <hy-picker
        v-model="value"
        has-input
        :columns="columns"
        :input="{ placeholder: '请选择国家' }"
        @confirm="onConfirm"
    ></hy-picker>
</template>

<script setup>
    import { ref, reactive } from 'vue'

    const value = ref('')
    const columns = reactive([['中国', '美国', '日本']])

    const onConfirm = (e) => {
        console.log('选中:', e.value)
    }
</script>

多列模式

html
<template>
    <hy-picker
        v-model="value"
        has-input
        :columns="columns"
        separator="-"
        @confirm="onConfirm"
    ></hy-picker>
</template>

<script setup>
    import { ref, reactive } from 'vue'

    const value = ref([])
    const columns = reactive([
        ['周一', '周二', '周三', '周四', '周五'],
        ['上午', '下午', '晚上'],
        ['9:00', '10:00', '11:00', '14:00', '15:00', '16:00']
    ])

    const onConfirm = (e) => {
        console.log('选中:', e.value)
    }
</script>

多列联动

html
<template>
    <hy-picker
        v-model="value"
        ref="pickerRef"
        has-input
        :columns="columns"
        @change="onChange"
        @confirm="onConfirm"
    ></hy-picker>
</template>

<script setup>
    import { ref, reactive } from 'vue'

    const pickerRef = ref(null)
    const value = ref([])

    const columns = reactive([
        ['中国', '美国'],
        ['北京', '上海', '广州']
    ])

    const cityData = reactive({
        中国: ['北京', '上海', '广州', '深圳'],
        美国: ['纽约', '洛杉矶', '芝加哥', '休斯顿']
    })

    const onChange = (e) => {
        const { columnIndex, value } = e
        if (columnIndex === 0) {
            const selectedCountry = value[0]
            pickerRef.value.setColumnValues(1, cityData[selectedCountry])
        }
    }

    const onConfirm = (e) => {
        console.log('联动选择:', e.value)
    }
</script>

对象数据格式

html
<template>
    <hy-picker
        v-model="value"
        has-input
        :columns="columns"
        label-key="label"
        value-key="value"
        @confirm="onConfirm"
    ></hy-picker>
</template>

<script setup>
    import { ref, reactive } from 'vue'

    const value = ref('')
    const columns = reactive([
        [
            { label: '雪月夜', value: 2021 },
            { label: '冷夜雨', value: 804 },
            { label: '清风颂', value: 305 }
        ]
    ])

    const onConfirm = (e) => {
        console.log('选中:', e.value)
    }
</script>

自定义弹窗位置

html
<template>
    <hy-picker :show="show" :columns="columns" popup-mode="top" @confirm="onConfirm"></hy-picker>
    <hy-cell clickable @click="show = true">
        <hy-cell-item title="顶部弹窗" :value="value"></hy-cell-item>
    </hy-cell>
</template>

<script setup>
    import { ref, reactive } from 'vue'

    const show = ref(false)
    const value = ref('')
    const columns = reactive([['选项1', '选项2', '选项3']])

    const onConfirm = (e) => {
        value.value = e.value.join('')
        show.value = false
    }
</script>

自定义工具栏按钮

html
<template>
    <hy-picker
        :show="show"
        :columns="columns"
        cancel-text="取消选择"
        confirm-text="确认选择"
        cancel-color="#999999"
        confirm-color="#4F8EF7"
        title="自定义标题"
        @confirm="onConfirm"
        @cancel="onCancel"
    ></hy-picker>
    <hy-cell clickable @click="show = true">
        <hy-cell-item title="自定义按钮" :value="value"></hy-cell-item>
    </hy-cell>
</template>

<script setup>
    import { ref, reactive } from 'vue'

    const show = ref(false)
    const value = ref('')
    const columns = reactive([['选项A', '选项B', '选项C']])

    const onConfirm = (e) => {
        value.value = e.value.join('')
        show.value = false
    }

    const onCancel = () => {
        show.value = false
    }
</script>

自定义输入框样式

html
<template>
    <hy-picker
        v-model="value"
        has-input
        :columns="columns"
        :input="{ 
            placeholder: '请选择',
            fontSize: 16,
            prefixIcon: 'calendar',
            border: false
        }"
    ></hy-picker>
</template>

<script setup>
    import { ref, reactive } from 'vue'

    const value = ref('')
    const columns = reactive([['选项1', '选项2', '选项3']])
</script>

设置默认选中项

html
<template>
    <hy-picker
        :show="show"
        :columns="columns"
        :defaultIndex="[1, 2]"
        @confirm="onConfirm"
    ></hy-picker>
    <hy-cell clickable @click="show = true">
        <hy-cell-item title="默认选中" :value="value"></hy-cell-item>
    </hy-cell>
</template>

<script setup>
    import { ref, reactive } from 'vue'

    const show = ref(false)
    const value = ref('')
    const columns = reactive([
        ['A', 'B', 'C', 'D'],
        ['1', '2', '3', '4']
    ])

    const onConfirm = (e) => {
        value.value = e.value.join(' / ')
        show.value = false
    }
</script>

禁用点击遮罩关闭

html
<template>
    <hy-picker
        :show="show"
        :columns="columns"
        :closeOnClickOverlay="false"
        title="必须点击按钮关闭"
        @confirm="onConfirm"
    ></hy-picker>
    <hy-cell clickable @click="show = true">
        <hy-cell-item title="禁用遮罩关闭" :value="value"></hy-cell-item>
    </hy-cell>
</template>

<script setup>
    import { ref, reactive } from 'vue'

    const show = ref(false)
    const value = ref('')
    const columns = reactive([['选项1', '选项2', '选项3']])

    const onConfirm = (e) => {
        value.value = e.value.join('')
        show.value = false
    }
</script>

自定义插槽内容

html
<template>
    <hy-picker v-model="value" has-input :columns="columns" title="自定义标题" ref="pickerRef">
        <!-- 自定义输入框内容 -->
        <template #default>
            <view class="custom-input">
                <text>自定义内容: {{ value }}</text>
            </view>
        </template>

        <!-- 自定义工具栏右侧 -->
        <template #toolbar-right>
            <hy-button text="保存" size="small" @click="handleSave"></hy-button>
        </template>

        <!-- 工具栏下方自定义区域 -->
        <template #toolbar-bottom>
            <view class="toolbar-tip">
                <text>请选择您的选项</text>
            </view>
        </template>
    </hy-picker>
</template>

<script setup>
    import { ref, reactive } from 'vue'

    const pickerRef = ref(null)
    const value = ref('')
    const columns = reactive([['选项1', '选项2', '选项3']])

    const handleSave = () => {
        console.log('保存:', value.value)
        pickerRef.value.onConfirm()
    }
</script>

API

Picker Props

参数说明类型默认值
modelValue回显到输入框的值(hasInput为true时必须设置)string|number|array-
show是否显示选择器(hasInput为true时不用设置)booleanfalse
popupMode弹窗弹出模式[1]stringbottom
separator多列分隔符string/
showToolbar是否显示顶部操作栏booleantrue
title顶部标题string-
columns设置每一列的数据,支持一维数组(单列)或二维数组(多列)array[]
loading是否显示加载中状态booleanfalse
itemHeight各列中单个选项的高度(px)number44
cancelText取消按钮文字string取消
confirmText确认按钮文字string确定
cancelColor取消按钮颜色string#909193
confirmColor确认按钮颜色string-
visibleItemCount每列可见选项数量number5
labelKey选项对象中显示文本对应的键名stringlabel
valueKey选项对象中值对应的键名stringvalue
closeOnClickOverlay是否允许点击遮罩关闭选择器booleanfalse
defaultIndex各列默认索引array[]
immediateChange是否在手指松开时立即触发change事件booleantrue
zIndex弹窗层级number10076
hasInput是否显示输入框booleanfalse
input输入框配置属性,hasInput为true时生效,详见输入框ApiHyInputProps{}
toolbarRightSlot是否启用工具栏右侧插槽(需配合slot="toolbar-right"使用)booleanfalse

Events

事件名说明回调参数
close关闭选择器时触发-
confirm点击确定按钮,返回当前选择的值{ indexs, value, values }
change当选择值变化时触发{ columnIndex, index, indexs, value, values }
cancel点击取消按钮时触发-

change 事件参数说明

参数说明类型
columnIndex发生变化的列索引number
index当前列选中的索引number
indexs所有列的索引数组array
value当前选中的值(数组)array
values所有列的数据(二维数组)array

confirm 事件参数说明

参数说明类型
indexs所有列的索引数组array
value当前选中的值(数组)array
values所有列的数据(二维数组)array

Methods

通过 ref 调用以下方法:

方法名说明参数
setColumnValues设置指定列的选项数据columnIndex: number 列索引, values: array 新数据
onConfirm手动触发确认选择-
close关闭选择器弹窗-

Slots

插槽名说明回调参数
default自定义输入框内容(hasInput为true时生效)-
toolbar-right工具栏右侧内容,需同时设置 toolbarRightSlot="true" 才能生效(微信小程序限制)-
toolbar-bottom工具栏下方自定义区域-

typings

类型说明
ts
interface PickerColumnVo {
    /** 值(必填) */
    value: string | number
    /** 显示文本 */
    label?: string
    /** 自定义属性 */
    [key: string]: any
}

interface SelectValueVo {
    /** 当前选中的值(数组) */
    value: string[]
    /** 当前列选中的索引 */
    index?: number
    /** 所有列的索引数组 */
    indexs?: number[]
    /** 所有列的数据(二维数组) */
    values?: Array<any>
    /** 发生变化的列索引 */
    columnIndex?: number
}

interface IPickerExpose {
    /** 设置某一列的值 */
    setColumnValues: (columnIndex: number, values: Array<string | PickerColumnVo>) => void
    /** 手动触发确认选择 */
    onConfirm: () => void
    /** 关闭选择器弹窗 */
    close: () => void
}
13:35

  1. bottom:底部弹出;top:顶部弹出 ↩︎