Picker 选择器

用于从预设选项中选择值的选择器组件

该组件目前处于实验性阶段,API 及功能可能会有较大调整,欢迎试用并提供反馈
<script setup lang="ts">
import { ref } from 'vue'

const singleValue = ref('banana')
const singleColumnData = [
  { label: '苹果', value: 'apple' },
  { label: '香蕉', value: 'banana' },
  { label: '橙子', value: 'orange' },
  { label: '葡萄', value: 'grape' },
  { label: '草莓', value: 'strawberry' },
]
</script>

<template>
  <div class="w-full p-4">
    <SkPicker v-model="singleValue" :columns="singleColumnData" />
  </div>
</template>

用法

Controlled 选中值

Prop类型默认值描述
v-modelstring | number | (string|number)[][]设置选择器的选中值 (双向绑定)
<script setup lang="ts">
import { ref } from 'vue'

const singleValue = ref('orange')
const singleColumnData = [
  { label: '苹果', value: 'apple' },
  { label: '香蕉', value: 'banana' },
  { label: '橙子', value: 'orange' },
  { label: '葡萄', value: 'grape' },
  { label: '草莓', value: 'strawberry' },
]
</script>

<template>
  <div class="w-full p-4">
    <SkPicker v-model="singleValue" :columns="singleColumnData" />

    <text class="text-body-medium font-medium">
      选中值:{{ JSON.stringify(singleValue) }}
    </text>
  </div>
</template>

Columns 选项列表

Prop类型默认值描述
columnsT = SkPickerOption[] | SkPickerOption[][]-选项列表。
选项列表没有类型约束,默认类型是 SkPickerOption[]SkPickerOption[][],如果你columns格式是自定义,可以通过 transform 函数来转换成规范性格式。
SkPickerOption类型描述
labelstring显示文本
valuestring | number选项值
disabledboolean是否禁用
subSkPickerOption[]子选项(级联)

单列选择

<script setup lang="ts">
import { ref } from 'vue'

const singleValue = ref('orange')
const singleColumnData = [
  { label: '苹果', value: 'apple' },
  { label: '香蕉', value: 'banana' },
  { label: '橙子', value: 'orange' },
  { label: '葡萄', value: 'grape' },
  { label: '草莓', value: 'strawberry' },
]
</script>

<template>
  <div class="w-full p-4">
    <SkPicker v-model="singleValue" :columns="singleColumnData" />

    <text class="text-body-medium font-medium">
      选中值:{{ JSON.stringify(singleValue) }}
    </text>
  </div>
</template>

多列选择

<script setup lang="ts">
import { ref } from 'vue'

const multiValue = ref(['banana', 'orange'])
const multiColumnData = [
  [
    { label: '苹果', value: 'apple' },
    { label: '香蕉', value: 'banana' },
    { label: '橙子', value: 'orange' },
    { label: '葡萄', value: 'grape' },
    { label: '草莓', value: 'strawberry' },
  ],
  [
    { label: '红色', value: 'red' },
    { label: '橙色', value: 'orange' },
    { label: '黄色', value: 'yellow' },
    { label: '绿色', value: 'green' },
    { label: '蓝色', value: 'blue' },
  ],
]
</script>

<template>
  <div class="w-full p-4">
    <SkPicker v-model="multiValue" :columns="multiColumnData" />

    <text class="text-body-medium font-medium">
      选中值:{{ JSON.stringify(multiValue) }}
    </text>
  </div>
</template>

级联选择

<script setup lang="ts">
import { ref } from 'vue'

const value = ref(['fruit', 'melons', 'watermelon'])

// 创建级联数据
const cascadeData = [
  {
    label: '水果',
    value: 'fruit',
    sub: [
      {
        label: '瓜果类',
        value: 'melons',
        sub: [
          { label: '西瓜', value: 'watermelon' },
          { label: '哈密瓜', value: 'cantaloupe' },
        ],
      },
      {
        label: '柑橘类',
        value: 'citrus',
        sub: [
          { label: '橙子', value: 'orange' },
          { label: '柠檬', value: 'lemon' },
        ],
      },
    ],
  },
  {
    label: '食材',
    value: 'food',
    sub: [
      {
        label: '海鲜',
        value: 'seafood',
        sub: [
          { label: '', value: 'fish' },
          { label: '', value: 'crab' },
        ],
      },
    ],
  },
]
</script>

<template>
  <div class="w-full p-4">
    <SkPicker v-model="value" :columns="cascadeData" />

    <text class="text-body-medium font-medium">
      选中值:{{ JSON.stringify(value) }}
    </text>
  </div>
</template>

ItemHeight 选项高度

Prop类型默认值描述
itemHeightnumber44设置每个选项的高度(px)
<script setup lang="ts">
import { ref } from 'vue'

const itemHeight = ref('36')

const value = ref('medium')
const sizeOptions = [
  { label: '小号 (36px)', value: 'small' },
  { label: '中号 (44px)', value: 'medium' },
  { label: '大号 (56px)', value: 'large' },
]
</script>

<template>
  <div class="w-full p-4 space-y-6">
    <SkPicker v-model="value" :columns="sizeOptions" :item-height="Number(itemHeight)" />

    <SkRadioGroup v-model="itemHeight" orientation="horizontal" clax="mt-1" @change="value = 'small'">
      <SkRadio value="36" label="36px" />
      <SkRadio value="44" label="44px" />
      <SkRadio value="56" label="56px" />
    </SkRadioGroup>
  </div>
</template>

VisibleItemCount 可见选项数量

Prop类型默认值描述
visibleItemCountnumber5设置可见选项的数量
<script setup lang="ts">
import { ref } from 'vue'

const visibleItemCount = ref('3')

const value = ref('option3')
const options = [
  { label: '选项 1', value: 'option1' },
  { label: '选项 2', value: 'option2' },
  { label: '选项 3', value: 'option3' },
  { label: '选项 4', value: 'option4' },
  { label: '选项 5', value: 'option5' },
  { label: '选项 6', value: 'option6' },
  { label: '选项 7', value: 'option7' },
  { label: '选项 8', value: 'option8' },
  { label: '选项 9', value: 'option9' },
]
</script>

<template>
  <div class="w-full p-4 space-y-6">
    <SkPicker v-model="value" :columns="options" :visible-item-count="Number(visibleItemCount)" />

    <SkRadioGroup v-model="visibleItemCount" orientation="horizontal" clax="mt-1" @change="value = 'option1'">
      <SkRadio value="3" label="3项" />
      <SkRadio value="5" label="5项" />
      <SkRadio value="7" label="7项" />
    </SkRadioGroup>
  </div>
</template>

Disabled 禁用

Prop类型默认值描述
disabledbooleanfalse设置选择器是否为禁用状态
<script setup lang="ts">
import { ref } from 'vue'

const isDisabled = ref(true)

const normalValue = ref('banana')
const options = [
  { label: '苹果', value: 'apple' },
  { label: '香蕉', value: 'banana' },
  { label: '橙子', value: 'orange' },
  { label: '葡萄', value: 'grape' },
  { label: '草莓', value: 'strawberry' },
]
</script>

<template>
  <div class="w-full p-4">
    <SkPicker v-model="normalValue" :columns="options" :disabled="isDisabled" />

    <SkButton size="small" @click="isDisabled = !isDisabled">
      {{ isDisabled ? '启用' : '禁用' }}滚动
    </SkButton>
  </div>
</template>

Transform 选项转换函数

Prop类型默认值描述
transform(data: T) => SkPickerOption[] | SkPickerOption[][]-自定义数据转换函数,用于转换非标准格式数据
SkPickerOption类型描述
labelstring显示文本
valuestring | number选项值
disabledboolean是否禁用
subSkPickerOption[]子选项(级联)
<script setup lang="ts">
import { ref } from 'vue'

const value = ref(['1'])

// 非标准格式的数据
const rawData = [
  { id: 1, name: '北京', code: 'BJ', population: '2154万' },
  { id: 2, name: '上海', code: 'SH', population: '2489万' },
  { id: 3, name: '广州', code: 'GZ', population: '1881万' },
  { id: 4, name: '深圳', code: 'SZ', population: '1756万' },
  { id: 5, name: '杭州', code: 'HZ', population: '1220万' },
  { id: 6, name: '成都', code: 'CD', population: '2119万' },
]

// 数据转换函数
const transformData = (data: typeof rawData) => {
  return [
    data.map(item => ({
      label: `${item.name} (${item.code})`,
      value: item.id.toString(),
      population: item.population,
      code: item.code,
      name: item.name,
    })),
  ]
}
</script>

<template>
  <div class="w-full p-4">
    <SkPicker v-model="value" :columns="rawData" :transform="transformData" />
  </div>
</template>

例子

自定义选项渲染

通过 option 插槽可以自定义选项的渲染内容

<script setup lang="ts">
import { ref } from 'vue'

const value = ref('user1')
const userOptions = [
  { label: '张三', value: 'user1', avatar: '👨‍💼', role: '管理员', department: '技术部' },
  { label: '李四', value: 'user2', avatar: '👩‍💻', role: '开发者', department: '技术部' },
  { label: '王五', value: 'user3', avatar: '👨‍🎨', role: '设计师', department: '设计部' },
  { label: '赵六', value: 'user4', avatar: '👩‍💼', role: '产品经理', department: '产品部' },
]
</script>

<template>
  <div class="w-full p-4">
    <SkPicker v-model="value" :columns="userOptions" :item-height="60">
      <template #option="{ option, selected }">
        <div class="flex items-center justify-center space-x-3 w-full px-4">
          <span class="text-title-medium">{{ option.avatar }}</span>
          <div class="flex flex-col">
            <text class="font-medium text-base" :class="[selected ? 'text-brand' : 'text-gray-800']">
              {{ option.label }}
            </text>
            <text class="text-xs text-gray-500 mt-1">
              {{ option.role }} · {{ option.department }}
            </text>
          </div>
        </div>
      </template>
    </SkPicker>
  </div>
</template>

接口

Props

属性名类型默认值描述
v-modelstring | number | (string|number)[][]详见 Controlled 选中值
columnsSkPickerOption[] | SkPickerOption[][]-详见 Columns 选项列表
itemHeightnumber44详见 ItemHeight 选项高度
visibleItemCountnumber5详见 VisibleItemCount 可见选项数量
disabledbooleanfalse详见 Disabled 禁用
transform(data: T) => SkPickerOption[] | SkPickerOption[][]-详见 Transform 选项转换函数
claxSkRollerGroupUcvProps['clax']-用于拓展当前基础样式

Emits

事件名参数描述
change(event: any)当选择器的值发生变化时触发

Slots

插槽名属性描述
option{ option: SkPickerOption; selected: boolean; columnIndex: number }自定义选项内容

交互

正在完善中,敬请期待!😊