Picker 选择器 - Vant 4
🎯 Picker 选择器
🎯 介绍
Picker 组件提供多个选项集合供用户选择,支持单列选择、多列选择和级联选择,通常与弹出层组件配合使用。让选择操作更加便捷!
📦 引入
通过以下方式来全局注册组件,更多注册方式请参考组件注册。
import { createApp } from'vue'; import { Picker } from'vant'; const app = createApp(); app.use(Picker);🎯 代码演示
🔧 基础用法
Picker 就像一个万能的选择魔法师!🎩 通过 columns 属性配置选项数据,无论是字符串还是对象数组,都能轻松驾驭。顶部栏就像一个贴心的操作台,包含标题、确认和取消按钮,让用户的每一次选择都清晰明了。
<template>
<van-picker
title="请选择城市"
:columns="columns"
@confirm="onConfirm"
@cancel="onCancel"
@change="onChange"
/>
</template>import { showToast } from 'vant';
export default {
setup() {
const columns = [
{ text: '杭州', value: 'Hangzhou' },
{ text: '宁波', value: 'Ningbo' },
{ text: '温州', value: 'Wenzhou' },
{ text: '绍兴', value: 'Shaoxing' },
{ text: '湖州', value: 'Huzhou' },
];
const onConfirm = ({ selectedValues }) => {
showToast(`您选择了: ${selectedValues.join(',')}`);
};
const onChange = ({ selectedValues }) => {
console.log(`当前选择: ${selectedValues.join(',')}`);
};
const onCancel = () => showToast('取消选择');
return {
columns,
onChange,
onCancel,
onConfirm,
};
},
};🎭 搭配弹出层使用
在真实的应用场景中,Picker 就像一个优雅的舞者,经常与 Popup 和 Field 组件共舞!💃 这种组合让表单填写变得更加流畅自然,用户体验倍增。
<template>
<van-field
v-model="fieldValue"
is-link
readonly
label="选择城市"
placeholder="点击选择城市"
@click="showPicker = true"
/>
<van-popup v-model:show="showPicker" position="bottom">
<van-picker
title="选择城市"
:columns="columns"
@confirm="onConfirm"
@cancel="showPicker = false"
/>
</van-popup>
</template>import { ref } from 'vue';
export default {
setup() {
const columns = [
{ text: '杭州', value: 'Hangzhou' },
{ text: '宁波', value: 'Ningbo' },
{ text: '温州', value: 'Wenzhou' },
{ text: '绍兴', value: 'Shaoxing' },
{ text: '湖州', value: 'Huzhou' },
];
const fieldValue = ref('');
const showPicker = ref(false);
const onConfirm = ({ selectedValues, selectedOptions }) => {
showPicker.value = false;
fieldValue.value = selectedOptions[0].text;
};
return {
columns,
onConfirm,
fieldValue,
showPicker,
};
},
};🔄 双向绑定
想要实现数据的双向同步?v-model 就是你的最佳伙伴!🤝 它就像一座桥梁,连接着数据和视图,让选择状态与数据保持完美同步。
<template>
<van-picker
v-model="selectedValues"
title="城市选择"
:columns="columns"
/>
</template>import { ref } from 'vue';
export default {
setup() {
const columns = [
{ text: '杭州', value: 'Hangzhou' },
{ text: '宁波', value: 'Ningbo' },
{ text: '温州', value: 'Wenzhou' },
{ text: '绍兴', value: 'Shaoxing' },
{ text: '湖州', value: 'Huzhou' },
];
const selectedValues = ref(['Wenzhou']);
return {
columns,
selectedValues,
};
},
};📊 多列选择
需要同时选择多个维度的数据?多列选择就像一个多功能工具箱!🧰 通过二维数组配置,轻松实现复杂的组合选择,比如选择工作日和时间段。
<template>
<van-picker
title="选择时间"
:columns="columns"
@confirm="onConfirm"
/>
</template>import { showToast } from 'vant';
export default {
setup() {
const columns = [
// 第一列:星期
[
{ text: '周一', value: 'Monday' },
{ text: '周二', value: 'Tuesday' },
{ text: '周三', value: 'Wednesday' },
{ text: '周四', value: 'Thursday' },
{ text: '周五', value: 'Friday' },
],
// 第二列:时间段
[
{ text: '上午', value: 'Morning' },
{ text: '下午', value: 'Afternoon' },
{ text: '晚上', value: 'Evening' },
],
];
const onConfirm = ({ selectedValues }) => {
showToast(`选择了:${selectedValues.join(' ')}`);
};
return { columns, onConfirm };
},
};🌊 级联选择
级联选择就像一个智能导航系统!🗺️ 根据上级选择自动展示下级选项,让复杂的层级选择变得井然有序。省市区选择就是最经典的应用场景。
<template>
<van-picker
title="选择地区"
:columns="columns"
@confirm="onConfirm"
/>
</template>import { showToast } from 'vant';
export default {
setup() {
const columns = [
{
text: '浙江',
value: 'Zhejiang',
children: [
{
text: '杭州',
value: 'Hangzhou',
children: [
{ text: '西湖区', value: 'Xihu' },
{ text: '余杭区', value: 'Yuhang' },
],
},
{
text: '温州',
value: 'Wenzhou',
children: [
{ text: '鹿城区', value: 'Lucheng' },
{ text: '瓯海区', value: 'Ouhai' },
],
},
],
},
{
text: '福建',
value: 'Fujian',
children: [
{
text: '福州',
value: 'Fuzhou',
children: [
{ text: '鼓楼区', value: 'Gulou' },
{ text: '台江区', value: 'Taijiang' },
],
},
{
text: '厦门',
value: 'Xiamen',
children: [
{ text: '思明区', value: 'Siming' },
{ text: '海沧区', value: 'Haicang' },
],
},
],
},
];
const onConfirm = ({ selectedValues }) => {
showToast(`选择的地区:${selectedValues.join(' - ')}`);
};
return { columns, onConfirm };
},
};💡 小贴士:级联选择的数据嵌套深度需要保持一致,如果部分选项没有子选项,可以使用空字符串进行占位。
🚫 禁用选项
有些选项暂时不可用?通过设置 disabled 属性,就像给选项贴上"暂停服务"的标签!🏷️ 用户可以看到但无法选择,体验更加友好。
<template>
<van-picker
title="选择城市"
:columns="columns"
/>
</template>export default {
setup() {
const columns = [
{ text: '杭州', value: 'Hangzhou', disabled: true },
{ text: '宁波', value: 'Ningbo' },
{ text: '温州', value: 'Wenzhou' },
];
return { columns };
},
};⏳ 加载状态
数据还在路上?加载状态就像一个贴心的等待提示!⌛ 当选择器数据需要异步获取时,loading 属性会显示优雅的加载动画,让用户知道好东西正在准备中。
<template>
<van-picker
title="选择城市"
:columns="columns"
:loading="loading"
/>
</template>import { ref } from 'vue';
export default {
setup() {
const columns = ref([]);
const loading = ref(true);
// 模拟异步数据加载
setTimeout(() => {
columns.value = [
{ text: '杭州', value: 'Hangzhou' },
{ text: '宁波', value: 'Ningbo' },
{ text: '温州', value: 'Wenzhou' },
];
loading.value = false;
}, 2000);
return { columns, loading };
},
};📭 空状态
没有数据怎么办?空状态插槽就像一个友好的提示牌!📋 当数据为空时,可以自定义显示内容,让用户明白当前状况。
<template>
<van-picker title="选择城市" :columns="[]">
<template #empty>
<div class="empty-content">
<img src="empty-icon.png" alt="暂无数据" />
<p>暂无可选择的城市</p>
</div>
</template>
</van-picker>
</template>🔧 自定义 Columns 的结构
数据结构不标准?没关系!通过 columns-field-names 属性,就像给数据穿上合适的衣服!👔 让任何结构的数据都能完美适配。
<template>
<van-picker
title="选择地区"
:columns="columns"
:columns-field-names="customFieldName"
/>
</template>export default {
setup() {
const columns = [
{
cityName: '浙江',
cities: [
{
cityName: '杭州',
cities: [
{ cityName: '西湖区' },
{ cityName: '余杭区' }
],
},
{
cityName: '温州',
cities: [
{ cityName: '鹿城区' },
{ cityName: '瓯海区' }
],
},
],
},
{
cityName: '福建',
cities: [
{
cityName: '福州',
cities: [
{ cityName: '鼓楼区' },
{ cityName: '台江区' }
],
},
{
cityName: '厦门',
cities: [
{ cityName: '思明区' },
{ cityName: '海沧区' }
],
},
],
},
];
const customFieldName = {
text: 'cityName',
value: 'cityName',
children: 'cities',
};
return {
columns,
customFieldName,
};
},
};API
Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| v-model | 当前选中项对应的值,控制选择器的选中状态 🎯 | *number[] | string[]* |
| columns | 对象数组,配置每一列显示的数据,就像选择器的数据源 📊 | *PickerOption[] | PickerOption[][]* |
| columns-field-names | 自定义 columns 结构中的字段,让数据结构更灵活 🔧 | object | { text: 'text', value: 'value', children: 'children' } |
| title | 顶部栏标题,为选择器添加清晰的标识 📝 | string | - |
| confirm-button-text | 确认按钮文字,设置为空字符串可以隐藏按钮 ✅ | string | 确认 |
| cancel-button-text | 取消按钮文字,设置为空字符串可以隐藏按钮 ❌ | string | 取消 |
| toolbar-position | 顶部栏位置,可选值为 bottom,控制工具栏的显示位置 📍 | string | top |
| loading | 是否显示加载状态,数据加载时的友好提示 ⏳ | boolean | false |
| readonly | 是否为只读状态,只读状态下无法切换选项 🔒 | boolean | false |
| show-toolbar | 是否显示顶部栏,控制工具栏的显示与隐藏 🎛️ | boolean | true |
| allow-html | 是否允许选项内容中渲染 HTML,支持富文本显示 🎨 | boolean | false |
| option-height | 选项高度,支持 px``vw``vh``rem 单位,默认 px 📏 | *number | string* |
| visible-option-num | 可见的选项个数,控制选择器的视窗大小 👀 | *number | string* |
| swipe-duration | 快速滑动时惯性滚动的时长,单位 ms,影响滑动体验 ⚡ | *number | string* |
Events
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| confirm | 点击完成按钮时触发,确认选择操作 ✨ | { selectedValues, selectedOptions, selectedIndexes } |
| cancel | 点击取消按钮时触发,取消选择操作 🚫 | { selectedValues, selectedOptions, selectedIndexes } |
| change | 选中的选项改变时触发,实时响应选择变化 🔄 | { selectedValues, selectedOptions, selectedIndexes, columnIndex } |
| click-option | 点击选项时触发,捕获用户的点击行为 👆 | { currentOption, selectedValues, selectedOptions, selectedIndexes, columnIndex } |
scroll-into v4.2.1 | 当用户通过点击或拖拽让一个选项滚动到中间的选择区域时触发 🎯 | { currentOption, columnIndex } |
Slots
| 名称 | 说明 | 参数 |
|---|---|---|
| toolbar | 自定义整个顶部栏的内容,完全控制工具栏样式 🎛️ | - |
| title | 自定义标题内容,个性化标题显示 📝 | - |
| confirm | 自定义确认按钮内容,打造独特的确认按钮 ✅ | - |
| cancel | 自定义取消按钮内容,个性化取消按钮 ❌ | - |
| option | 自定义选项内容,完全控制选项的显示样式 🎨 | option: PickerOption, index: number |
| columns-top | 自定义选项上方内容,在选择区域上方添加内容 ⬆️ | - |
| columns-bottom | 自定义选项下方内容,在选择区域下方添加内容 ⬇️ | - |
empty v4.9.10 | 自定义空状态内容,当数据为空时的友好提示 📭 | - |
PickerOption 数据结构
| 键名 | 说明 | 类型 |
|---|---|---|
| text | 选项文字内容,显示给用户的文本 📝 | *string |
| value | 选项对应的值,用于数据绑定的实际值 🎯 | *string |
| disabled | 是否禁用选项,禁用后无法选择 🚫 | boolean |
| children | 级联选项,用于构建多级选择结构 🌊 | PickerOption[] |
| className | 选项额外类名,用于自定义样式 🎨 | *string |
方法
通过 ref 可以获取到 Picker 实例并调用实例方法,详见组件实例方法。
| 方法名 | 说明 | 参数 | 返回值 |
|---|---|---|---|
| confirm | 停止惯性滚动并触发 confirm 事件,手动确认选择 ✅ | - | - |
| getSelectedOptions | 获取当前选中的选项,返回完整的选项对象 📋 | - | *(PickerOption |
类型定义
组件导出以下类型定义:
import type {
PickerProps,
PickerColumn,
PickerOption,
PickerInstance,
PickerFieldNames,
PickerToolbarPosition,
PickerCancelEventParams,
PickerChangeEventParams,
PickerConfirmEventParams,
} from 'vant';PickerInstance 是组件实例的类型,用法如下:
import { ref } from 'vue';
import type { PickerInstance } from 'vant';
const pickerRef = ref<PickerInstance>();
pickerRef.value?.confirm();🎨 主题定制
样式变量
想要打造独一无二的选择器?这些 CSS 变量就是你的调色盘!🎨 通过自定义这些变量,可以轻松实现个性化的视觉效果。
| 名称 | 默认值 | 描述 |
|---|---|---|
| --van-picker-background | var(--van-background-2) | 选择器背景色,营造整体氛围 🎭 |
| --van-picker-toolbar-height | 44px | 工具栏高度,控制顶部操作区域大小 📏 |
| --van-picker-title-font-size | var(--van-font-size-lg) | 标题字体大小,突出标题重要性 📝 |
| --van-picker-title-line-height | var(--van-line-height-md) | 标题行高,优化文字显示效果 📐 |
| --van-picker-action-padding | 0 var(--van-padding-md) | 操作按钮内边距,调整按钮触摸区域 👆 |
| --van-picker-action-font-size | var(--van-font-size-md) | 操作按钮字体大小,保证按钮可读性 🔤 |
| --van-picker-confirm-action-color | var(--van-primary-color) | 确认按钮颜色,突出主要操作 ✅ |
| --van-picker-cancel-action-color | var(--van-text-color-2) | 取消按钮颜色,区分次要操作 ❌ |
| --van-picker-option-padding | 0 var(--van-padding-base) | 选项内边距,优化选项显示效果 📦 |
| --van-picker-option-font-size | var(--van-font-size-lg) | 选项字体大小,确保选项清晰可读 🔍 |
| --van-picker-option-text-color | var(--van-text-color) | 选项文字颜色,保持良好的对比度 🎨 |
| --van-picker-option-disabled-opacity | 0.3 | 禁用选项透明度,视觉上区分可用状态 👻 |
| --van-picker-mask-color | linear-gradient | 遮罩渐变色,营造聚焦效果 🌈 |
| --van-picker-loading-icon-color | var(--van-primary-color) | 加载图标颜色,保持品牌一致性 ⏳ |
| --van-picker-loading-mask-color | rgba(255, 255, 255, 0.9) | 加载遮罩颜色,提供加载状态反馈 🎭 |
❓ 常见问题
在桌面端无法操作组件?
参见桌面端适配。
📚 相关文档
- Popup 弹出层 - 功能强大的弹出层组件,常与 Picker 搭配使用 📱
- Field 输入框 - 表单输入组件,与 Picker 完美配合实现选择输入 ✏️
- DatePicker 日期选择 - 专门的日期选择器,基于 Picker 构建 📅
- TimePicker 时间选择 - 专门的时间选择器,时间选择的最佳选择 ⏰
- Cascader 级联选择 - 多级级联选择组件,处理复杂层级数据 🌊
- ActionSheet 动作面板 - 底部动作选择面板,另一种选择交互方式 📋
- PickerGroup 选择器组 - 多个选择器的组合管理 🎯
- ConfigProvider 全局配置 - 全局配置组件,统一管理主题样式 ⚙️