介绍
一个或多个可滚动列表选择器。
引入
js
import Picker from 'sard-uniapp/components/picker/picker.vue'代码演示
基础使用
通过 v-model 绑定当前值,通过 columns 配置选项数据。
vue
<template>
<sar-list card>
<sar-list-item>
<sar-picker v-model="value" :columns="columns" @change="onChange" />
</sar-list-item>
<sar-list-item
title="当前值:"
:value="JSON.stringify(value) ?? 'undefined'"
/>
<sar-list-item
title="设置为: 天津市"
arrow
hover
@click="value = '天津市'"
/>
<sar-list-item title="清空" arrow hover @click="value = undefined" />
</sar-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const columns = ['北京市', '天津市', '河北省', '山东省']
const value = ref<string | undefined>('河北省')
const onChange = (value: any) => {
console.log('change', value)
}
</script>vue
<template>
<sar-list card>
<sar-list-item>
<sar-picker v-model="value" :columns="columns" @change="onChange" />
</sar-list-item>
<sar-list-item
title="当前值:"
:value="JSON.stringify(value) ?? 'undefined'"
/>
<sar-list-item
title="设置为: 天津市"
arrow
hover
@click="value = '天津市'"
/>
<sar-list-item title="清空" arrow hover @click="value = undefined" />
</sar-list>
</template>
<script setup lang="js">
import { ref } from "vue";
const columns = ["\u5317\u4EAC\u5E02", "\u5929\u6D25\u5E02", "\u6CB3\u5317\u7701", "\u5C71\u4E1C\u7701"];
const value = ref("\u6CB3\u5317\u7701");
const onChange = (value2) => {
console.log("change", value2);
};
</script>对象类型
列的每一项可以为一个对象,使用 optionKeys 属性可以指定对象中哪个属性值为选中的值,哪个属性值为要显示的标签。
vue
<template>
<sar-list card>
<sar-list-item>
<sar-picker
v-model="value"
:columns="columns"
:option-keys="{ label: 'name', value: 'code' }"
/>
</sar-list-item>
<sar-list-item
title="当前值:"
:value="JSON.stringify(value) ?? 'undefined'"
/>
<sar-list-item title="设置为: 天津市" arrow hover @click="value = 120000" />
<sar-list-item title="清空" arrow hover @click="value = undefined" />
</sar-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const columns = [
{
code: 110000,
name: '北京市',
},
{
code: 120000,
name: '天津市',
},
{
code: 130000,
name: '河北省',
},
{
code: 140000,
name: '山东省',
},
]
const value = ref<number | undefined>(130000)
</script>vue
<template>
<sar-list card>
<sar-list-item>
<sar-picker
v-model="value"
:columns="columns"
:option-keys="{ label: 'name', value: 'code' }"
/>
</sar-list-item>
<sar-list-item
title="当前值:"
:value="JSON.stringify(value) ?? 'undefined'"
/>
<sar-list-item title="设置为: 天津市" arrow hover @click="value = 120000" />
<sar-list-item title="清空" arrow hover @click="value = undefined" />
</sar-list>
</template>
<script setup lang="js">
import { ref } from "vue";
const columns = [
{
code: 11e4,
name: "\u5317\u4EAC\u5E02"
},
{
code: 12e4,
name: "\u5929\u6D25\u5E02"
},
{
code: 13e4,
name: "\u6CB3\u5317\u7701"
},
{
code: 14e4,
name: "\u5C71\u4E1C\u7701"
}
];
const value = ref(13e4);
</script>多列
当 columns 属性值为一个二维数组时会显示为多列。
vue
<template>
<sar-list card>
<sar-list-item>
<sar-picker v-model="value" :columns="columns" />
</sar-list-item>
<sar-list-item
title="当前值:"
:value="JSON.stringify(value) ?? 'undefined'"
/>
<sar-list-item
title="设置为: 2003年10月"
arrow
hover
@click="value = ['2003年', '10月']"
/>
<sar-list-item title="清空" arrow hover @click="value = undefined" />
</sar-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const columns = [
Array(10)
.fill(0)
.map((_, index) => 2000 + index + '年'),
Array(12)
.fill(0)
.map((_, index) => 1 + index + '月'),
]
const value = ref<string[] | undefined>(['2005年', '5月'])
</script>vue
<template>
<sar-list card>
<sar-list-item>
<sar-picker v-model="value" :columns="columns" />
</sar-list-item>
<sar-list-item
title="当前值:"
:value="JSON.stringify(value) ?? 'undefined'"
/>
<sar-list-item
title="设置为: 2003年10月"
arrow
hover
@click="value = ['2003年', '10月']"
/>
<sar-list-item title="清空" arrow hover @click="value = undefined" />
</sar-list>
</template>
<script setup lang="js">
import { ref } from "vue";
const columns = [
Array(10).fill(0).map((_, index) => 2e3 + index + "\u5E74"),
Array(12).fill(0).map((_, index) => 1 + index + "\u6708")
];
const value = ref(["2005\u5E74", "5\u6708"]);
</script>对象类型多列
columns 属性值为对象类型的二维数组。
vue
<template>
<sar-list card>
<sar-list-item>
<sar-picker v-model="value" :columns="columns" />
</sar-list-item>
<sar-list-item
title="当前值:"
:value="JSON.stringify(value) ?? 'undefined'"
/>
<sar-list-item
title="设置为: 2003年10月"
arrow
hover
@click="value = [2003, 10]"
/>
<sar-list-item title="清空" arrow hover @click="value = undefined" />
</sar-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const columns = [
Array(10)
.fill(0)
.map((_, index) => ({
value: 2000 + index,
label: 2000 + index + '年',
})),
Array(12)
.fill(0)
.map((_, index) => ({
value: 1 + index,
label: 1 + index + '月',
})),
]
const value = ref<number[] | undefined>([2005, 5])
</script>vue
<template>
<sar-list card>
<sar-list-item>
<sar-picker v-model="value" :columns="columns" />
</sar-list-item>
<sar-list-item
title="当前值:"
:value="JSON.stringify(value) ?? 'undefined'"
/>
<sar-list-item
title="设置为: 2003年10月"
arrow
hover
@click="value = [2003, 10]"
/>
<sar-list-item title="清空" arrow hover @click="value = undefined" />
</sar-list>
</template>
<script setup lang="js">
import { ref } from "vue";
const columns = [
Array(10).fill(0).map((_, index) => ({
value: 2e3 + index,
label: 2e3 + index + "\u5E74"
})),
Array(12).fill(0).map((_, index) => ({
value: 1 + index,
label: 1 + index + "\u6708"
}))
];
const value = ref([2005, 5]);
</script>级联选择
当 columns 第一个元素为对象且其 children 属性值为数组时会被当作级联选择。
vue
<template>
<sar-list card>
<sar-list-item>
<sar-picker
v-model="value"
:columns="regionData"
:option-keys="{ label: 'name', value: 'code' }"
/>
</sar-list-item>
<sar-list-item
title="当前值:"
:value="JSON.stringify(value) ?? 'undefined'"
/>
<sar-list-item
title="设置为: 广东省/广州市/白云区"
arrow
hover
@click="value = [440000, 440100, 440111]"
/>
<sar-list-item title="清空" arrow hover @click="value = undefined" />
</sar-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { getRegionData } from 'region-data'
const regionData = getRegionData()
const value = ref<number[] | undefined>([150000, 150500, 150522])
</script>vue
<template>
<sar-list card>
<sar-list-item>
<sar-picker
v-model="value"
:columns="regionData"
:option-keys="{ label: 'name', value: 'code' }"
/>
</sar-list-item>
<sar-list-item
title="当前值:"
:value="JSON.stringify(value) ?? 'undefined'"
/>
<sar-list-item
title="设置为: 广东省/广州市/白云区"
arrow
hover
@click="value = [440000, 440100, 440111]"
/>
<sar-list-item title="清空" arrow hover @click="value = undefined" />
</sar-list>
</template>
<script setup lang="js">
import { ref } from "vue";
import { getRegionData } from "region-data";
const regionData = getRegionData();
const value = ref([15e4, 150500, 150522]);
</script>插槽
可通过 custom 插槽自定义每一个选项的内容。
INFO
因小程序不支持循环中的插槽,因此循环逻辑要自行实现;
因 picker-view-column 要为 picker-view 的直接子元素,因此要把 picker-view 提取出来,要自行绑定属性和事件。
vue
<template>
<sar-list card>
<sar-list-item>
<sar-picker
v-model="value"
:columns="columns"
:option-keys="{ label: 'name', value: 'name' }"
@change="onChange"
>
<template
#custom="{
columns,
maskClass,
pickerViewClass,
indicatorClass,
value,
onChange,
}"
>
<picker-view
:class="pickerViewClass"
:mask-class="maskClass"
:indicator-class="indicatorClass"
:value="value"
@change="onChange"
>
<picker-view-column v-for="(column, i) in columns" :key="i">
<sar-picker-item
v-for="(option, j) in column"
:key="j"
style="
display: flex;
justify-content: center;
align-items: center;
"
>
<sar-icon family="cake" :name="option.icon" />
<text style="margin-left: 16rpx">
{{ option.name }}
</text>
</sar-picker-item>
</picker-view-column>
</picker-view>
</template>
</sar-picker>
</sar-list-item>
<sar-list-item
title="当前值:"
:value="JSON.stringify(value) ?? 'undefined'"
/>
<sar-list-item title="设置为: 泡芙" arrow hover @click="value = '泡芙'" />
<sar-list-item title="清空" arrow hover @click="value = undefined" />
</sar-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { getPrizes } from '../../lucky-draw/demo/utils'
const columns = getPrizes()
const value = ref<string | undefined>('布丁')
const onChange = (value: any) => {
console.log('change', value)
}
</script>vue
<template>
<sar-list card>
<sar-list-item>
<sar-picker
v-model="value"
:columns="columns"
:option-keys="{ label: 'name', value: 'name' }"
@change="onChange"
>
<template
#custom="{
columns,
maskClass,
pickerViewClass,
indicatorClass,
value,
onChange,
}"
>
<picker-view
:class="pickerViewClass"
:mask-class="maskClass"
:indicator-class="indicatorClass"
:value="value"
@change="onChange"
>
<picker-view-column v-for="(column, i) in columns" :key="i">
<sar-picker-item
v-for="(option, j) in column"
:key="j"
style="
display: flex;
justify-content: center;
align-items: center;
"
>
<sar-icon family="cake" :name="option.icon" />
<text style="margin-left: 16rpx">
{{ option.name }}
</text>
</sar-picker-item>
</picker-view-column>
</picker-view>
</template>
</sar-picker>
</sar-list-item>
<sar-list-item
title="当前值:"
:value="JSON.stringify(value) ?? 'undefined'"
/>
<sar-list-item title="设置为: 泡芙" arrow hover @click="value = '泡芙'" />
<sar-list-item title="清空" arrow hover @click="value = undefined" />
</sar-list>
</template>
<script setup lang="js">
import { ref } from "vue";
import { getPrizes } from "../../lucky-draw/demo/utils";
const columns = getPrizes();
const value = ref("\u5E03\u4E01");
const onChange = (value2) => {
console.log("change", value2);
};
</script>API
PickerProps
| 属性 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| root-class | 组件根元素类名 | string | - |
| root-style | 组件根元素样式 | StyleValue | - |
| columns | 配置每一列的数据 | PickerOption[] | PickerOption[][] | [] |
| option-keys | 自定义 columns 结构中的字段 | OptionKeys | {label: 'label', value: 'value', children: 'children'} |
| model-value | 选中项的值 | any | - |
| immediate-change | 是否在手指松开时立即触发 update:model-value 事件 | boolean | false |
PickerSlots
| 插槽 | 描述 | 属性 |
|---|---|---|
| custom 1.17+ | 自定义选项的内容 | { columns: any[][]; value: number[]; pickerViewClass: string; maskClass: string; indicatorClass: string; onChange: (event: any) => void;} |
PickerEmits
| 事件 | 描述 | 类型 |
|---|---|---|
| update:model-value | 选中的选项改变时触发 | (value: any, selectedOptions: PickerOption[], indexes: number[]) => void |
| change 1.9.2+ | 选中的选项改变时触发 | (value: any, selectedOptions: PickerOption[], indexes: number[]) => void |
PickerOption
tsx
type PickerOption =
| {
[key: PropertyKey]: any
}
| number
| stringOptionKeys
tsx
interface OptionKeys {
label?: string
value?: string
children?: string
}主题定制
CSS 变量
scss
page,
.sar-portal {
--sar-picker-height: 480rpx;
--sar-picker-item-height: 96rpx;
--sar-picker-item-font-size: var(--sar-text-lg);
--sar-picker-item-color: var(--sar-body-color);
--sar-picker-indicator-border-color: var(--sar-border-color);
--sar-picker-mask-bg-image:
linear-gradient(
to bottom,
rgba(var(--sar-emphasis-bg-rgb), 0.95),
rgba(var(--sar-emphasis-bg-rgb), 0.6)
),
linear-gradient(
to top,
rgba(var(--sar-emphasis-bg-rgb), 0.95),
rgba(var(--sar-emphasis-bg-rgb), 0.6)
);
}