Roller 滚动器

用于滚动选择的基础组件

该组件目前处于实验性阶段,API 及功能可能会有较大调整,欢迎试用并提供反馈
<template>
  <div class="p-4 w-full">
    <SkRollerGroup>
      <SkRoller
        :options="[
          { label: '苹果', value: 'apple' },
          { label: '香蕉', value: 'banana' },
          { label: '橙子', value: 'orange' },
          { label: '葡萄', value: 'grape' },
          { label: '草莓', value: 'strawberry' },
        ]"
      />
    </SkRollerGroup>
  </div>
</template>
SkRoller 组件需要配合 SkRollerGroup 组件进行使用,前者提供数据控制,后者提供容器、遮罩效果和尺寸控制

用法 (Roller)

Options 选项

Prop类型默认值描述
optionsSkRollerOption[]-设置滚动器的选项列表
SkRollerOption类型描述
labelstring选项显示的文本
valuestring | number选项的值
disabledboolean是否禁用该选项(可选)
<script setup lang="ts">
import { ref } from 'vue'

const selectedOption = ref('watermelon')

const options = [
  { label: '苹果', value: 'apple' },
  { label: '香蕉', value: 'banana' },
  { label: '橙子', value: 'orange' },
  { label: '葡萄', value: 'grape' },
  { label: '草莓', value: 'strawberry' },
  { label: '西瓜', value: 'watermelon' },
  { label: '芒果', value: 'mango' },
  { label: '菠萝', value: 'pineapple' },
  { label: '梨子', value: 'pear' },
  { label: '桃子', value: 'peach' },
  { label: '李子', value: 'plum' },
  { label: '樱桃', value: 'cherry' },
  { label: '龙眼', value: 'longan' },
  { label: '柚子', value: 'grapefruit' },
  { label: '猕猴桃', value: 'kiwi' },
  { label: '哈密瓜', value: 'melon' },
  { label: '荔枝', value: 'lychee' },
  { label: '橄榄', value: 'olive' },
  { label: '石榴', value: 'pomegranate' },
]
</script>

<template>
  <div class="p-4 w-full">
    <SkRollerGroup>
      <SkRoller v-model="selectedOption" :options="options" />
    </SkRollerGroup>
  </div>
</template>

Controlled 选中值

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

const selectedOption = ref('apple')

const options = [
  { label: '苹果', value: 'apple' },
  { label: '香蕉', value: 'banana' },
  { label: '橙子', value: 'orange' },
  { label: '葡萄', value: 'grape' },
  { label: '草莓', value: 'strawberry' },
  // ... 更多选项
]
</script>

<template>
  <div class="p-4 w-full">
    <SkRollerGroup>
      <SkRoller v-model="selectedOption" :options="options" />
    </SkRollerGroup>

    <SkButton label="吃葡萄" size="small" @click="selectedOption = 'grape'" />
  </div>
</template>

Disabled 禁用

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

const isDisabled = ref(false)

const value = ref('apple')

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

<template>
  <div class="p-4 w-full">
    <SkRollerGroup>
      <SkRoller v-model="value" :options="options" :disabled="isDisabled" />
    </SkRollerGroup>

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

用法 (RollerGroup)

ItemHeight 项目高度

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

const itemHeight = ref('44')

const value = ref('option2')

const options = [
  { label: '选项 1', value: 'option1' },
  { label: '选项 2', value: 'option2' },
  { label: '选项 3', value: 'option3' },
  { label: '选项 4', value: 'option4' },
  { label: '选项 5', value: 'option5' },
]
</script>

<template>
  <div class="p-4 w-full">
    <SkRollerGroup :item-height="Number(itemHeight)">
      <SkRoller v-model="value" :options="options" />
    </SkRollerGroup>

    <SkRadioGroup v-model="itemHeight" orientation="horizontal" clax="mt-1" @change="value = 'option1'">
      <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('option2')

const options = [
  { label: '选项 1', value: 'option1' },
  { label: '选项 2', value: 'option2' },
  { label: '选项 3', value: 'option3' },
  { label: '选项 4', value: 'option4' },
  { label: '选项 5', value: 'option5' },
]
</script>

<template>
  <div class="p-4 w-full">
    <SkRollerGroup :visible-item-count="Number(visibleItemCount)">
      <SkRoller v-model="value" :options="options" />
    </SkRollerGroup>

    <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>

例子

多列选择

通过在 SkRollerGroup 中放置多个 SkRoller 组件,可以实现多列选择功能。

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

const selectedCuisine = ref('chinese')
const selectedPrice = ref('medium')
const selectedDistance = ref('1km')

const cuisineOptions = [
  { label: '中餐', value: 'chinese' },
  { label: '西餐', value: 'western' },
  { label: '日料', value: 'japanese' },
  { label: '韩料', value: 'korean' },
  { label: '泰餐', value: 'thai' },
]

const priceOptions = [
  { label: '', value: 'budget' },
  { label: '¥¥', value: 'medium' },
  { label: '¥¥¥', value: 'expensive' },
]

const distanceOptions = [
  { label: '500米', value: '500m' },
  { label: '1公里', value: '1km' },
  { label: '3公里', value: '3km' },
  { label: '5公里', value: '5km' },
]
</script>

<template>
  <div class="p-4 w-full box-border">
    <SkRollerGroup>
      <SkRoller v-model="selectedCuisine" :options="cuisineOptions" />
      <SkRoller v-model="selectedPrice" :options="priceOptions" />
      <SkRoller v-model="selectedDistance" :options="distanceOptions" />
    </SkRollerGroup>
  </div>
</template>

自定义选项模板

通过 option 插槽可以自定义选项的显示内容,实现更丰富的视觉效果。

图标的设置可以配合 SkIcon 组件进行使用,前往获取该组件更多信息
<script setup lang="ts">
import { ref } from 'vue'

const selectedCity = ref('beijing')

const cityOptions = [
  { label: '北京', value: 'beijing', icon: 'i-lucide:building-2', description: '首都' },
  { label: '上海', value: 'shanghai', icon: 'i-lucide:landmark', description: '魔都' },
  { label: '广州', value: 'guangzhou', icon: 'i-lucide:palmtree', description: '花城' },
  { label: '深圳', value: 'shenzhen', icon: 'i-lucide:zap', description: '科技之城' },
  { label: '杭州', value: 'hangzhou', icon: 'i-lucide:waves', description: '人间天堂' },
  { label: '成都', value: 'chengdu', icon: 'i-lucide:coffee', description: '天府之国' },
  { label: '西安', value: 'xian', icon: 'i-lucide:castle', description: '古都' },
]
</script>

<template>
  <div class="p-4 w-full">
    <SkRollerGroup :item-height="56" :visible-item-count="5">
      <SkRoller v-model="selectedCity" :options="cityOptions">
        <template #option="{ option, selected }">
          <div class="flex items-center gap-3">
            <SkIcon :name="option.icon" size="24rpx" :clax="selected ? 'text-brand' : 'text-neutral'" />
            <span class="font-bold" :class="selected ? 'text-brand' : 'text-neutral'">
              {{ option.label }}
            </span>
            <span class="text-xs" :class="selected ? 'text-description' : 'text-placeholder'">
              {{ option.description }}
            </span>
          </div>
        </template>
      </SkRoller>
    </SkRollerGroup>
  </div>
</template>

接口 (Roller)

Props

属性名类型默认值描述
v-modelstring | number-详见 Controlled 选中值
optionsSkRollerOption[]-详见 Options 选项
disabledbooleanfalse详见 Disabled 禁用

Emits

事件名参数描述
change(value: unknown, option: SkRollerOption)当选中值改变时触发

Slots

插槽名属性描述
option{ option: SkRollerOption, selected: boolean }自定义选项内容

接口 (RollerGroup)

Props

属性名类型默认值描述
itemHeightnumber44详见 ItemHeight 项目高度
visibleItemCountnumber5详见 VisibleItemCount 可见项数量

Slots

插槽名属性描述
default-放置 SkRoller 组件的内容

交互

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