Cascader カスケード選択 - Vant 4
🔗 紹介
ショッピング中に配送先住所を選択する場面を想像してください 📍。都道府県から市、さらに区まで、階層を追って精度よく位置を特定します。Cascader カスケード選択コンポーネントは、複雑な階層データの中を容易に移動するためのスマートな「地図ナビゲーター」のようなものです 🗺️!
都道府県市区町村の三段階連動、商品カテゴリーの絞り込み、組織構造の選択など、Cascader はもともと煩雑だった多段階選択を滑らかな体験に変えてくれます ✨。まるで親切なガイドのように、ユーザーを一歩一歩最終目標に導き、複雑なデータ構造を簡単かつ理解しやすいものにします!
📦 導入
以下の方法でグローバルにコンポーネントを登録します。詳細な登録方法についてはコンポーネントの登録を参照してください。
import { createApp } from'vue';
import { Cascader } from'vant';
const app = createApp();
app.use(Cascader);🎯 コード例
基本的な使い方
積み木を組み立てるように簡単です 🧱!Cascader は Field と Popup コンポーネントと完璧に連携し、まるで三人の仲間が手をつないで、滑らかな選択体験を作り上げます。
入力ボックスをクリックすると、階層選択パネルが表示され、階層を選択していくと、最終的なパスが自動的に完全な選択結果につなぎ合わされます 🎯。この体験は面白い「宝探しゲーム」をしているようで、一歩一歩が期待に満ちています!
<van-field
v-model="fieldValue"
is-link
readonly
label="地域"
placeholder="地域を選択してください"
@click="show = true"
/>
<van-popup v-model:show="show" round position="bottom" style="height: 80%">
<van-cascader
v-model="cascaderValue"
title="地域を選択"
:options="options"
@close="show = false"
@finish="onFinish"
/>
</van-popup>
```js
import { ref } from'vue';
export default {
setup() {
const show = ref(false);
const fieldValue = ref('');
const cascaderValue = ref('');
// オプションリスト、childrenは子オプションを表し、多段階ネストに対応
const options = [ { text: '浙江省', value: '330000', children: [{ text: '杭州市', value: '330100' }], }, { text: '江苏省', value: '320000', children: [{ text: '南京市', value: '320100' }], }, ];
// すべてのオプションが選択されると、finishイベントがトリガーされます
const onFinish = ({ selectedOptions }) => {
show.value = false;
fieldValue.value = selectedOptions.map((option) => option.text).join('/');
};
return { show, options, onFinish, fieldValue, cascaderValue, };
}
};中国の省市区データ
ECアプリを開発する際の最大の悩みは何でしょうか?もちろん省市区データですよね 😅!心配しないでください。Vant は親切な執事のように、あなたのために完全な中国の省市区データを準備しています 🇨🇳。
このデータは「地理百科事典」のようなもので、黒竜江から海南まで、新疆から上海まで、あらゆる地域が含まれています!小さな npm パッケージをインストールするだけで、アプリケーションに瞬時に全国の住所選択機能を追加できます 🚀:
# npm で
npm i @vant/area-data
# yarn で
yarn add @vant/area-data
# pnpm で
pnpm add @vant/area-data
# Bun で
bun add @vant/area-data<van-cascader
v-model="value"
:options="options"
active-color="#07c160"
/>
```js
import { ref } from'vue';
import { useCascaderAreaData } from'@vant/area-data';
export default { setup() {
const show = ref(false);
const fieldValue = ref('');
const cascaderValue = ref('');
const options = useCascaderAreaData();
const onFinish = ({ selectedOptions }) => { show.value = false; fieldValue.value = selectedOptions.map((option) => option.text).join('/'); };
return { show, options, onFinish, fieldValue, cascaderValue, };
},
};Tips: 中国の行政区域は毎年変更されることがあります。省市区データが最新の状態でないことを発見した場合は、Pull Request を提出して更新を手伝ってください。最新のデータは「国家統計局 - 全国区画コード」 および「民政部 - 行政区域コード」で確認できます。公式データに基づいて検証してください。
カスタムカラー
カスケードセレクターをより個性的にしたいですか?🎨 active-color 属性は魔法のペンのようなもので、選択状態に好みの色を塗ることができます!
ブランドブルー、活力あるオレンジ、優雅なパープルなど、あらゆる色でコンポーネントを際立たせ、アプリケーションの全体的なデザインスタイルに完璧に溶け込ませることができます ✨。
<van-cascader
v-model="value"
:options="options"
:field-names="fieldNames"
/>
### 非同期でオプションを読み込む
データが多すぎると、一度に読み込むとユーザーが長い間待たされてしまいます 🌸。そんな時、非同期読み込みは「スマートな配達人」のような存在です 📦。必要に応じて配送し、ユーザーがどの階層まで選択したかに応じて、その階層のデータを読み込みます。
`change` イベントをリッスンすることで、ユーザーが選択したときに動的に下級データを取得し、選択プロセスをスムーズかつ効率的にすることができます!
```html
<van-cascader v-model="value" :options="options">
<template #options-top="{ tabIndex }">
<div class="custom-header">
第 {{ tabIndex + 1 }} 階層のオプション
</div>
</template>
</van-cascader>
```js
import { ref } from'vue';
import { closeToast, showLoadingToast } from'vant';
export default { setup() {
const show = ref(false);
const fieldValue = ref('');
const cascaderValue = ref('');
const options = ref([ { text: '浙江省', value: '330000', children: [], }, ]);
const onChange = ({ value }) => {
if ( value === options.value[0].value && options.value[0].children.length === 0 ) {
// データリクエストのシミュレーション
showLoadingToast('読み込み中...');
setTimeout(() => {
options.value[0].children = [ { text: '杭州市', value: '330100' }, { text: '寧波市', value: '330200' }, ];
closeToast(); }, 1000);
}
};
const onFinish = ({ selectedOptions }) => { show.value = false; fieldValue.value = selectedOptions.map((option) => option.text).join('/'); };
return { show, options, onFinish, fieldValue, cascaderValue, };
},
};カスタムフィールド名
各プロジェクトには独自の「言語習慣」があります 🗣️。name を使いたい人もいれば、title を好む人もいますし、label にこだわる人もいます。Cascader は「通訳」のような存在です 🌐。field-names 属性を通じて、データ構造とコンポーネントを完璧に接続することができます!
バックエンドの同僚がどのフィールド名を使っていても、Cascader は簡単に適応し、データの接続を圧倒的に簡単にします 💪。
import { ref } from'vue'; exportdefault { setup() { const code = ref(''); const fieldNames = { text: 'name', value: 'code', children: 'items', }; const options = [ { name: '浙江省', code: '330000', items: [{ name: '杭州市', code: '330100' }], }, { name: '江苏省', code: '320000', items: [{ name: '南京市', code: '320100' }], }, ]; return { code, options, fieldNames, }; }, };オプションの上側にカスタムコンテンツを追加
オプションリストの上に「調味料」を追加したいですか 🧂?検索ボックス、説明文、または可愛いアイコンなど?
スロットの魔法を使えば、各階層のオプションの上に任意のコンテンツを追加することができ、選択体験をさらに豊かにすることができます 🌈!
import { ref } from'vue'; exportdefault { setup() { const code = ref(''); const options = [ { name: '浙江省', code: '330000', items: [{ name: '杭州市', code: '330100' }], }, { name: '江苏省', code: '320000', items: [{ name: '南京市', code: '320100' }], }, ]; return { code, options, }; }, };API
Props
| パラメータ | 説明 | タイプ | デフォルト値 |
|---|---|---|---|
| v-model | 選択されたアイテムの値 | string | number | - |
| title | 上部タイトル | string | - |
| options | 選択可能なデータソース | CascaderOption[] | [] |
| placeholder | 未選択時のプロンプトテキスト | string | 選択してください |
| active-color | 選択状態のハイライトカラー | string | #1989fa |
| swipeable | 左右スワイプでタブを切り替えるかどうか | boolean | true | | closeable | 閉じるアイコンを表示するかどうか | boolean | true | | show-header | ヘッダーを表示するかどうか | boolean | true | | close-icon | 閉じるアイコンの名前または画像URL、Iconコンポーネントのname属性と同じ | string | cross |
| field-names | options 構造内のフィールドをカスタマイズ | CascaderFieldNames | { text: 'text', value: 'value', children: 'children' } |
CascaderOption データ構造
options 属性はオブジェクトからなる配列で、配列内の各オブジェクトが選択肢を設定します。オブジェクトには以下の値を含めることができます:
| キー名 | 説明 | タイプ |
|---|---|---|
| text | オプションのテキスト(必須) | string |
| value | オプションに対応する値(必須) | string | number |
| color | オプションのテキストカラー | string |
| children | 子オプションリスト | CascaderOption[] |
| disabled | オプションを無効にするかどうか | boolean |
| className | 対応する列に追加のclassを追加する | string | Array | object |
Events
| イベント | 説明 | コールバックパラメータ |
|---|---|---|
| change | 選択されたアイテムが変更されたときにトリガー | { value: string | number, selectedOptions: CascaderOption[], tabIndex: number } |
| finish | すべてのオプションの選択が完了した後にトリガー | { value: string | number, selectedOptions: CascaderOption[], tabIndex: number } |
| close | 閉じるアイコンをクリックしたときにトリガー | - |
| click-tab | タブをクリックしたときにトリガー | tabIndex: number, title: string |
Slots
| 名前 | 説明 | パラメータ |
|---|---|---|
| title | カスタム上部タイトル | - |
| option | カスタムオプションテキスト | { option: CascaderOption, selected: boolean } |
| options-top | オプションの上側のカスタムコンテンツ | { tabIndex: number } |
| options-bottom | オプションの下側のカスタムコンテンツ | { tabIndex: number } |
型定義
コンポーネントは以下の型定義をエクスポートしています:
importtype { CascaderProps, CascaderOption, CascaderFieldNames } from'vant';テーマカスタマイズ
スタイル変数
コンポーネントは以下の CSS 変数を提供しており、スタイルのカスタマイズに使用できます。使用方法については ConfigProvider コンポーネント を参照してください。
| 名前 | デフォルト値 | 説明 |
|---|---|---|
| --van-cascader-header-height | 48px | - |
| --van-cascader-header-padding | 0 var(--van-padding-md) | - |
| --van-cascader-title-font-size | var(--van-font-size-lg) | - |
| --van-cascader-title-line-height | 20px | - |
| --van-cascader-close-icon-size | 22px | - |
| --van-cascader-close-icon-color | var(--van-gray-5) | - |
| --van-cascader-selected-icon-size | 18px | - |
| --van-cascader-tabs-height | 48px | - |
| --van-cascader-active-color | var(--van-danger-color) | - |
| --van-cascader-options-height | 384px | - |
| --van-cascader-option-disabled-color | var(--van-text-color-3) | - |
| --van-cascader-tab-color | var(--van-text-color) | - |
| --van-cascader-unselected-tab-color | var(--van-text-color-2) | - |
🎯 ベストプラクティス
💡 推奨使用シーン
Cascader は万能の「分類マスター」のようなもので、様々なシーンで重要な役割を果たします:
🏠 住所選択
<!-- 典型的な省市区三段階連動 -->
<van-cascader
v-model="addressCode"
title="住所を選択"
:options="areaOptions"
@finish="onAddressFinish"
/>🏢 組織構造選択
<!-- 会社部署階層の選択 -->
<van-cascader
v-model="departmentId"
title="部署を選択"
:options="departmentOptions"
placeholder="所属部署を選択してください"
/>📱 商品カテゴリー絞り込み
<!-- EC商品カテゴリー選択 -->
<van-cascader
v-model="categoryId"
title="商品カテゴリー"
:options="categoryOptions"
active-color="#ff6034"
/>📚 知識分類ナビゲーション
<!-- ドキュメントまたは知識ベースの分類 -->
<van-cascader
v-model="topicId"
title="トピックを選択"
:options="topicOptions"
:field-names="{ text: 'title', value: 'id', children: 'subTopics' }"
/>⚡ パフォーマンス最適化のヒント
- データの遅延読み込み:大量のデータに対しては、非同期読み込みを使用して最初のレンダリングの遅延を避ける
- 適切な階層の深さ:3〜4階層に制限することを推奨します。深すぎるとユーザー体験が損なわれます
- データキャッシュ:比較的固定されたデータ(地域情報など)については、ローカルキャッシュを行うことができます
- 仮想スクロール:単一階層のオプションが多い場合、仮想スクロールを使用してパフォーマンスを最適化します
🎨 デザインのアドバイス
- 階層の指示:明確なタブデザインにより、ユーザーが現在の選択階層を認識できるようにします
- 選択状態:明確な選択状態のフィードバックにより、ユーザーが自分の選択を明確に把握できるようにします
- ロード状態:非同期読み込み時には、ユーザーフレンドリーなロード通知を提供します
- エラー処理:ネットワーク異常時には、再試行メカニズムとエラー通知を提供します
🔧 よくある質問と解決策
Q: 検索機能を実装するにはどうすればよいですか? A: options-top スロットを使用して検索ボックスを追加し、データフィルタリングと組み合わせて検索を実現できます。
Q: デフォルトの選択値を設定するにはどうすればよいですか? A: v-model の初期値をターゲットオプションの value に設定するだけです。
Q: 非同期読み込みが失敗した場合はどうすればよいですか? A: change イベントにエラー処理を追加し、再試行ボタンまたはエラー通知を提供します。
Q: 選択階層を制限するにはどうすればよいですか? A: データ構造内の children の階層の深さを制御するか、change イベントで判断することができます。
🎪 高度な使い方の例
動的にオプションを無効にする
// ビジネスロジックに基づいて特定のオプションを動的に無効にする
const processOptions = (options, parentValue) => {
return options.map(option => ({
...option,
disabled: shouldDisableOption(option, parentValue),
children: option.children ? processOptions(option.children, option.value) : []
}));
};カスタムオプションのレンダリング
<van-cascader v-model="value" :options="options">
<template #option="{ option, selected }">
<div class="custom-option">
<span>{{ option.text }}</span>
<van-icon v-if="option.hot" name="fire" color="red" />
<van-tag v-if="selected" size="mini" type="primary">選択済み</van-tag>
</div>
</template>
</van-cascader>🔗 関連コンポーネント
- Picker 選択器 - 単列または複列の選択器
- DatePicker 日付選択 - 専用の日付時間選択
- Area 省市区選択 - 専用の地域選択コンポーネント
- TreeSelect 分類選択 - ツリー構造の分類選択
- Field 入力ボックス - Cascader と一緒によく使用されます
- Popup ポップアップ - Cascader のコンテナコンポーネント
📚 関連リソース
💡 ヒント:優れたカスケード選択器は優れたガイドのようなものです。道の行き方を知っているだけでなく、観光客が選択プロセスで気軽に楽しめるようにする必要があります。Cascader の様々な機能を合理的に活用することで、複雑なデータ選択をシンプルかつ楽しいものに変えることができます!