Vant4 Picker 選擇器

2023-02-16 17:55 更新

介紹

提供多個(gè)選項(xiàng)集合供用戶(hù)選擇,支持單列選擇、多列選擇和級(jí)聯(lián)選擇,通常與彈出層組件配合使用。

引入

通過(guò)以下方式來(lái)全局注冊(cè)組件,更多注冊(cè)方式請(qǐng)參考組件注冊(cè)。

import { createApp } from 'vue';
import { Picker } from 'vant';

const app = createApp();
app.use(Picker);

代碼演示

基礎(chǔ)用法

選項(xiàng)配置

Picker 組件通過(guò) ?columns? 屬性配置選項(xiàng)數(shù)據(jù),?columns? 是一個(gè)包含字符串或?qū)ο蟮臄?shù)組。

頂部欄

頂部欄包含標(biāo)題、確認(rèn)按鈕和取消按鈕,點(diǎn)擊確認(rèn)按鈕觸發(fā) ?confirm? 事件,點(diǎn)擊取消按鈕觸發(fā) ?cancel? 事件。

<van-picker
  title="標(biāo)題"
  :columns="columns"
  @confirm="onConfirm"
  @cancel="onCancel"
  @change="onChange"
/>
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(`當(dāng)前值: ${selectedValues.join(',')}`);
    };
    const onChange = ({ selectedValues }) => {
      showToast(`當(dāng)前值: ${selectedValues.join(',')}`);
    };
    const onCancel = () => showToast('取消');

    return {
      columns,
      onChange,
      onCancel,
      onConfirm,
    };
  },
};

搭配彈出層使用

在實(shí)際場(chǎng)景中,Picker 通常作為用于輔助表單填寫(xiě),可以搭配 Popup 和 Field 實(shí)現(xiàn)該效果。

<van-field
  v-model="value"
  is-link
  readonly
  label="城市"
  placeholder="選擇城市"
  @click="showPicker = true"
/>
<van-popup v-model:show="showPicker" round position="bottom">
  <van-picker
    :columns="columns"
    @cancel="showPicker = false"
    @confirm="onConfirm"
  />
</van-popup>
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 result = ref('');
    const showPicker = ref(false);

    const onConfirm = ({ selectedOptions }) => {
      showPicker.value = false;
      fieldValue.value = selectedOptions[0].text;
    };

    return {
      result,
      columns,
      onConfirm,
      showPicker,
    };
  },
};

雙向綁定

通過(guò) ?v-model? 可以綁定當(dāng)前選中項(xiàng)的 ?values?,修改 ?v-model? 綁定的值時(shí),Picker 的選中狀態(tài)也會(huì)隨之改變。

?v-model? 的值是一個(gè)數(shù)組,數(shù)組的第一位對(duì)應(yīng)第一列選中項(xiàng)的 ?value?,第二位對(duì)應(yīng)第二列選中項(xiàng)的 ?value?,以此類(lèi)推。

<van-picker v-model="selectedValues" title="標(biāo)題" :columns="columns" />
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 selectedValues = ref(['Wenzhou']);

    return {
      columns,
      selectedValues,
    };
  },
};

多列選擇

?columns? 屬性可以通過(guò)二維數(shù)組的形式配置多列選擇。

<van-picker title="標(biāo)題" :columns="columns" />
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' },
      ],
    ];

    return { columns };
  },
};

級(jí)聯(lián)選擇

使用 ?columns? 的 ?children? 字段可以實(shí)現(xiàn)選項(xiàng)級(jí)聯(lián)的效果。如果級(jí)聯(lián)層級(jí)較多,推薦使用 Cascader 級(jí)聯(lián)選項(xiàng)組件

<van-picker title="標(biāo)題" :columns="columns" />
export default {
  setup() {
    const columns = [
      {
        text: '浙江',
        value: 'Zhejiang',
        children: [
          {
            text: '杭州',
            value: 'Hangzhou',
            children: [
              { text: '西湖區(qū)', value: 'Xihu' },
              { text: '余杭區(qū)', value: 'Yuhang' },
            ],
          },
          {
            text: '溫州',
            value: 'Wenzhou',
            children: [
              { text: '鹿城區(qū)', value: 'Lucheng' },
              { text: '甌海區(qū)', value: 'Ouhai' },
            ],
          },
        ],
      },
      {
        text: '福建',
        value: 'Fujian',
        children: [
          {
            text: '福州',
            value: 'Fuzhou',
            children: [
              { text: '鼓樓區(qū)', value: 'Gulou' },
              { text: '臺(tái)江區(qū)', value: 'Taijiang' },
            ],
          },
          {
            text: '廈門(mén)',
            value: 'Xiamen',
            children: [
              { text: '思明區(qū)', value: 'Siming' },
              { text: '海滄區(qū)', value: 'Haicang' },
            ],
          },
        ],
      },
    ];

    return { columns };
  },
};
級(jí)聯(lián)選擇的數(shù)據(jù)嵌套深度需要保持一致,如果部分選項(xiàng)沒(méi)有子選項(xiàng),可以使用空字符串進(jìn)行占位。

禁用選項(xiàng)

選項(xiàng)可以為對(duì)象結(jié)構(gòu),通過(guò)設(shè)置 ?disabled? 來(lái)禁用該選項(xiàng)。

<van-picker :columns="columns" />
export default {
  setup() {
    const columns = [
      { text: '杭州', value: 'Hangzhou', disabled: true },
      { text: '寧波', value: 'Ningbo' },
      { text: '溫州', value: 'Wenzhou' },
    ];
    return { columns };
  },
};

加載狀態(tài)

若選擇器數(shù)據(jù)是異步獲取的,可以通過(guò) ?loading? 屬性顯示加載提示。

<van-picker :columns="columns" :loading="loading" />
import { ref } from 'vue';

export default {
  setup() {
    const columns = ref([]);
    const loading = ref(true);

    setTimeout(() => {
      columns.value = [{ text: '選項(xiàng)', value: 'option' }];
      loading.value = false;
    }, 1000);

    return { columns, loading };
  },
};

自定義 Columns 的結(jié)構(gòu)

<van-picker
  :title="標(biāo)題"
  :columns="columns"
  :columns-field-names="customFieldName"
/>
export default {
  setup() {
    const columns = [
      {
        cityName: '浙江',
        cities: [
          {
            cityName: '杭州',
            cities: [{ cityName: '西湖區(qū)' }, { cityName: '余杭區(qū)' }],
          },
          {
            cityName: '溫州',
            cities: [{ cityName: '鹿城區(qū)' }, { cityName: '甌海區(qū)' }],
          },
        ],
      },
      {
        cityName: '福建',
        cities: [
          {
            cityName: '福州',
            cities: [{ cityName: '鼓樓區(qū)' }, { cityName: '臺(tái)江區(qū)' }],
          },
          {
            cityName: '廈門(mén)',
            cities: [{ cityName: '思明區(qū)' }, { cityName: '海滄區(qū)' }],
          },
        ],
      },
    ];

    const customFieldName = {
      text: 'cityName',
      value: 'cityName',
      children: 'cities',
    };

    return {
      columns,
      customFieldName,
    };
  },
};

API

Props

參數(shù) 說(shuō)明 類(lèi)型 默認(rèn)值
columns 對(duì)象數(shù)組,配置每一列顯示的數(shù)據(jù) PickerOption[] | PickerOption[][] []
columns-field-names 自定義 columns 結(jié)構(gòu)中的字段 object { text: 'text', value: 'value', children: 'children' }
title 頂部欄標(biāo)題 string -
confirm-button-text 確認(rèn)按鈕文字 string 確認(rèn)
cancel-button-text 取消按鈕文字 string 取消
toolbar-position 頂部欄位置,可選值為 bottom string top
loading 是否顯示加載狀態(tài) boolean false
show-toolbar 是否顯示頂部欄 boolean true
allow-html 是否允許選項(xiàng)內(nèi)容中渲染 HTML boolean false
option-height 選項(xiàng)高度,支持 px vw vh rem 單位,默認(rèn) px number | string 44
visible-option-num 可見(jiàn)的選項(xiàng)個(gè)數(shù) number | string 6
swipe-duration 快速滑動(dòng)時(shí)慣性滾動(dòng)的時(shí)長(zhǎng),單位 ms number | string 1000

Events

事件名 說(shuō)明 回調(diào)參數(shù)
confirm 點(diǎn)擊完成按鈕時(shí)觸發(fā) { selectedValues, selectedOptions, selectedIndexes }
cancel 點(diǎn)擊取消按鈕時(shí)觸發(fā) { selectedValues, selectedOptions, selectedIndexes }
change 選項(xiàng)改變時(shí)觸發(fā) { selectedValues, selectedOptions, selectedIndexes, columnIndex }
click-option 點(diǎn)擊選項(xiàng)時(shí)觸發(fā) { currentOption, selectedValues, selectedOptions, selectedIndexes, columnIndex }

Slots

名稱(chēng) 說(shuō)明 參數(shù)
toolbar v3.1.2 自定義整個(gè)頂部欄的內(nèi)容 -
title 自定義標(biāo)題內(nèi)容 -
confirm 自定義確認(rèn)按鈕內(nèi)容 -
cancel 自定義取消按鈕內(nèi)容 -
option 自定義選項(xiàng)內(nèi)容 option: PickerOption
columns-top 自定義選項(xiàng)上方內(nèi)容 -
columns-bottom 自定義選項(xiàng)下方內(nèi)容 -

PickerOption 數(shù)據(jù)結(jié)構(gòu)

鍵名 說(shuō)明 類(lèi)型
text 選項(xiàng)文字內(nèi)容 string | number
value 選項(xiàng)對(duì)應(yīng)的值 string | number
disabled 是否禁用選項(xiàng) boolean
children 級(jí)聯(lián)選項(xiàng) PickerOption[]
className 選項(xiàng)額外類(lèi)名 string | Array | object

方法

通過(guò) ref 可以獲取到 Picker 實(shí)例并調(diào)用實(shí)例方法,詳見(jiàn)組件實(shí)例方法。

方法名 說(shuō)明 參數(shù) 返回值
confirm 停止慣性滾動(dòng)并觸發(fā) confirm 事件 - -
getSelectedOptions 獲取當(dāng)前選中的選項(xiàng) - (PickerOption | undefined)[]

類(lèi)型定義

組件導(dǎo)出以下類(lèi)型定義:

import type {
  PickerProps,
  PickerColumn,
  PickerOption,
  PickerInstance,
  PickerFieldNames,
  PickerToolbarPosition,
  PickerCancelEventParams,
  PickerChangeEventParams,
  PickerConfirmEventParams,
} from 'vant';

?PickerInstance? 是組件實(shí)例的類(lèi)型,用法如下:

import { ref } from 'vue';
import type { PickerInstance } from 'vant';

const pickerRef = ref<PickerInstance>();

pickerRef.value?.confirm();

主題定制

樣式變量

組件提供了下列 CSS 變量,可用于自定義樣式,使用方法請(qǐng)參考 ConfigProvider 組件。

名稱(chēng) 默認(rèn)值 描述
--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-link-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) -

常見(jiàn)問(wèn)題

在桌面端無(wú)法操作組件?

參見(jiàn)桌面端適配。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)