Skip to content
API 风格:

Cascader カスケードセレクト ​

カスケードセレクトは複数階層のデータを扱う場面で使用します。例:省・市・地区の選択。

基本的な使い方 ​

単独で使用
vue
<script setup>
import { ref } from 'vue'

const value1 = ref([])
const options1 = [
  {
    value: 'zhinan',
    label: 'ガイド',
    children: [
      {
        value: 'sheji',
        label: 'デザインガイド',
        children: [
          { value: 'yuansze', label: '色' },
          { value: 'fuziyuanze', label: 'フォント' },
        ],
      },
      {
        value: 'shejiguize',
        label: 'デザインルール',
      },
    ],
  },
  {
    value: 'zujian',
    label: 'コンポーネント',
    children: [
      { value: 'jiben', label: '基本' },
      { value: 'fankui', label: 'フィードバック' },
    ],
  },
]
</script>

<template>
  <!-- 基本的な使い方 -->
  <lh-cascader v-model="value1" :options="options1" />
</template>
vue
<script>
export default {
  data() {
    return {
      value1: [],
      options1: [
        {
          value: 'zhinan',
          label: 'ガイド',
          children: [
            {
              value: 'sheji',
              label: 'デザインガイド',
              children: [
                { value: 'yuansze', label: '色' },
                { value: 'fuziyuanze', label: 'フォント' },
              ],
            },
            {
              value: 'shejiguize',
              label: 'デザインルール',
            },
          ],
        },
        {
          value: 'zujian',
          label: 'コンポーネント',
          children: [
            { value: 'jiben', label: '基本' },
            { value: 'fankui', label: 'フィードバック' },
          ],
        },
      ],
    }
  },
}
</script>

<template>
  <!-- 基本的な使い方 -->
  <lh-cascader v-model="value1" :options="options1" />
</template>

複数選択モード ​

複数選択モードを設定すると、複数の結果を選択できます。

複数選択モード
vue
<script setup>
import { ref } from 'vue'

const value2 = ref([])
const options2 = [
  {
    value: 'zhinan',
    label: 'ガイド',
    children: [
      { value: 'sheji', label: 'デザインガイド' },
      { value: 'shejiguize', label: 'デザインルール' },
    ],
  },
  {
    value: 'zujian',
    label: 'コンポーネント',
    children: [
      { value: 'jiben', label: '基本コンポーネント' },
      { value: 'fankui', label: 'フィードバックコンポーネント' },
    ],
  },
]
</script>

<template>
  <!-- 複数選択モード -->
  <lh-cascader v-model="value2" :options="options2" multiple />
</template>
vue
<script>
export default {
  data() {
    return {
      value2: [],
      options2: [
        {
          value: 'zhinan',
          label: 'ガイド',
          children: [
            { value: 'sheji', label: 'デザインガイド' },
            { value: 'shejiguize', label: 'デザインルール' },
          ],
        },
        {
          value: 'zujian',
          label: 'コンポーネント',
          children: [
            { value: 'jiben', label: '基本コンポーネント' },
            { value: 'fankui', label: 'フィードバックコンポーネント' },
          ],
        },
      ],
    }
  },
}
</script>

<template>
  <!-- 複数選択モード -->
  <lh-cascader v-model="value2" :options="options2" multiple />
</template>

オプションの無効化 ​

disabled 属性でノードを無効化します。

オプションの無効化
vue
<script setup>
import { ref } from 'vue'

const value3 = ref([])
const options3 = [
  {
    value: 'zhinan',
    label: 'ガイド',
    disabled: true,
    children: [
      { value: 'sheji', label: 'デザインガイド' },
    ],
  },
  {
    value: 'zujian',
    label: 'コンポーネント',
    children: [
      { value: 'jiben', label: '基本コンポーネント' },
      { value: 'fankui', label: 'フィードバックコンポーネント', disabled: true },
    ],
  },
]
</script>

<template>
  <!-- オプションの無効化 -->
  <lh-cascader v-model="value3" :options="options3" />
</template>
vue
<script>
export default {
  data() {
    return {
      value3: [],
      options3: [
        {
          value: 'zhinan',
          label: 'ガイド',
          disabled: true,
          children: [
            { value: 'sheji', label: 'デザインガイド' },
          ],
        },
        {
          value: 'zujian',
          label: 'コンポーネント',
          children: [
            { value: 'jiben', label: '基本コンポーネント' },
            { value: 'fankui', label: 'フィードバックコンポーネント', disabled: true },
          ],
        },
      ],
    }
  },
}
</script>

<template>
  <!-- オプションの無効化 -->
  <lh-cascader v-model="value3" :options="options3" />
</template>

サイズ・無効化・読み取り専用 ​

size でサイズを調整し、disabled でセレクタ全体を無効化し、readonly で読み取り専用表示にし、placeholder でプレースホルダーをカスタマイズし、clearable でクリアボタンをオフにします。

サイズ・無効化・読み取り専用
vue
<script setup lang="ts">
import { ref } from 'vue'

const demoCascSize = ref([])
const demoCascSize2 = ref([])
const demoCascDisabled = ref([])
const demoCascReadonly = ref([])
const demoCascPlaceholder = ref([])
const demoCascNoClear = ref([])
const options = [
  {
    value: 'zhinan',
    label: 'ガイド',
    children: [
      { value: 'sheji', label: 'デザインガイド' },
      { value: 'shejiguize', label: 'デザインルール' },
    ],
  },
  {
    value: 'zujian',
    label: 'コンポーネント',
    children: [
      { value: 'jiben', label: '基本コンポーネント' },
      { value: 'fankui', label: 'フィードバックコンポーネント' },
    ],
  },
]
</script>

<template>
  <!-- small -->
  <lh-cascader v-model="demoCascSize" :options="options" size="small" placeholder="small" />
  <!-- large -->
  <lh-cascader v-model="demoCascSize2" :options="options" size="large" placeholder="large" />
  <!-- 無効状態 -->
  <lh-cascader v-model="demoCascDisabled" :options="options" disabled placeholder="無効状態" />
  <!-- 読み取り専用 -->
  <lh-cascader v-model="demoCascReadonly" :options="options" readonly placeholder="読み取り専用" />
  <!-- カスタムプレースホルダー -->
  <lh-cascader v-model="demoCascPlaceholder" :options="options" placeholder="カスタムプレースホルダー" />
  <!-- クリア不可 -->
  <lh-cascader v-model="demoCascNoClear" :options="options" :clearable="false" placeholder="クリア不可" />
</template>
vue
<script>
export default {
  data() {
    return {
      demoCascSize: [],
      demoCascSize2: [],
      demoCascDisabled: [],
      demoCascReadonly: [],
      demoCascPlaceholder: [],
      demoCascNoClear: [],
      options: [
        {
          value: 'zhinan',
          label: 'ガイド',
          children: [
            { value: 'sheji', label: 'デザインガイド' },
            { value: 'shejiguize', label: 'デザインルール' },
          ],
        },
        {
          value: 'zujian',
          label: 'コンポーネント',
          children: [
            { value: 'jiben', label: '基本コンポーネント' },
            { value: 'fankui', label: 'フィードバックコンポーネント' },
          ],
        },
      ],
    }
  },
}
</script>

<template>
  <!-- small -->
  <lh-cascader v-model="demoCascSize" :options="options" size="small" placeholder="small" />
  <!-- large -->
  <lh-cascader v-model="demoCascSize2" :options="options" size="large" placeholder="large" />
  <!-- 無効状態 -->
  <lh-cascader v-model="demoCascDisabled" :options="options" disabled placeholder="無効状態" />
  <!-- 読み取り専用 -->
  <lh-cascader v-model="demoCascReadonly" :options="options" readonly placeholder="読み取り専用" />
  <!-- カスタムプレースホルダー -->
  <lh-cascader v-model="demoCascPlaceholder" :options="options" placeholder="カスタムプレースホルダー" />
  <!-- クリア不可 -->
  <lh-cascader v-model="demoCascNoClear" :options="options" :clearable="false" placeholder="クリア不可" />
</template>

パス表示と検索 ​

  • show-all-levels は入力ボックスに完全なパスを表示するかどうかを制御します(デフォルト true。オフにすると末尾の階層名のみ表示);
  • separator はパスの区切り文字をカスタマイズします。検索結果パネルにも同じものが適用されます;
  • emit-path を false に設定すると v-model は末尾のノードの値のみバインドします。入力ボックスは完全なパスを表示し続けます;
  • check-strictly は任意の階層のノードを選択可能にします(任意の階層をクリックすると直接選択され、子階層の閲覧はホバーでの展開に依存します);
  • filterable で検索を有効にします。キーワードを入力すると完全なパスで一致項目を表示します;
  • collapse-tags は複数選択モードでタグを折りたたみます;
  • cascading で親子ノードの連動チェックをオフにします;
  • item-config でノードのフィールドエイリアスをカスタマイズします(例: id / name でツリーを構築)。パス表示にも同じものが適用されます。

以下の例はすべて選択値をあらかじめ設定しているため、階層を順にクリックしなくても違いを比較できます。完全なパスは 浙江省/杭州市/西湖区 と表示され、show-all-levels をオフにすると 西湖区 のみ表示され、separator=" > " の場合は 浙江省 > 杭州市 > 西湖区 と表示されます。

パス表示と検索
浙江省/杭州市/西湖区
+1
浙江省/杭州市/西湖区
浙江省/杭州市/浜江区
vue
<script setup lang="ts">
import { ref } from 'vue'

const demoCascFullPath = ref(['zhejiang', 'hangzhou', 'xihu'])
const demoCascAllLevels = ref(['zhejiang', 'hangzhou', 'xihu'])
const demoCascSep = ref(['zhejiang', 'hangzhou', 'xihu'])
const demoCascEmit = ref(['xihu'])
const demoCascStrict = ref(['zhejiang', 'hangzhou'])
const demoCascFilter = ref([])
const demoCascCollapse = ref(['xihu', 'haishu'])
const demoCascLoose = ref(['xihu', 'binjiang'])
const demoCascItem = ref(['zhejiang', 'hangzhou', 'xihu'])

const pathOptions = [
  {
    value: 'zhejiang',
    label: '浙江省',
    children: [
      {
        value: 'hangzhou',
        label: '杭州市',
        children: [
          { value: 'xihu', label: '西湖区' },
          { value: 'binjiang', label: '浜江区' },
        ],
      },
      {
        value: 'ningbo',
        label: '寧波市',
        children: [{ value: 'haishu', label: '海曙区' }],
      },
    ],
  },
  {
    value: 'jiangsu',
    label: '江蘇省',
    children: [
      {
        value: 'nanjing',
        label: '南京市',
        children: [{ value: 'xuanwu', label: '玄武区' }],
      },
    ],
  },
]

const aliasedOptions = [
  {
    id: 'zhejiang',
    name: '浙江省',
    sub: [
      {
        id: 'hangzhou',
        name: '杭州市',
        sub: [
          { id: 'xihu', name: '西湖区' },
          { id: 'binjiang', name: '浜江区' },
        ],
      },
      {
        id: 'ningbo',
        name: '寧波市',
        sub: [{ id: 'haishu', name: '海曙区' }],
      },
    ],
  },
]
</script>

<template>
  <!-- 完全なパス(デフォルト) -->
  <lh-cascader v-model="demoCascFullPath" :options="pathOptions" placeholder="完全なパス(デフォルト)" />
  <!-- 末尾のみ表示 -->
  <lh-cascader v-model="demoCascAllLevels" :options="pathOptions" :show-all-levels="false" placeholder="末尾のみ表示" />
  <!-- 区切り文字 > -->
  <lh-cascader v-model="demoCascSep" :options="pathOptions" separator=" > " placeholder="区切り文字 >" />
  <!-- 末尾の値のみ返す -->
  <lh-cascader v-model="demoCascEmit" :options="pathOptions" :emit-path="false" placeholder="末尾の値のみ返す" />
  <!-- 任意の階層を選択可能 -->
  <lh-cascader v-model="demoCascStrict" :options="pathOptions" check-strictly placeholder="任意の階層を選択可能" />
  <!-- 検索可能 -->
  <lh-cascader v-model="demoCascFilter" :options="pathOptions" filterable placeholder="検索可能" />
  <!-- 複数選択のタグ折りたたみ -->
  <lh-cascader v-model="demoCascCollapse" :options="pathOptions" multiple collapse-tags placeholder="複数選択のタグ折りたたみ" />
  <!-- 親子で連動しない -->
  <lh-cascader v-model="demoCascLoose" :options="pathOptions" multiple :cascading="false" placeholder="親子で連動しない" />
  <!-- フィールドエイリアス -->
  <lh-cascader v-model="demoCascItem" :options="aliasedOptions" :item-config="{ value: 'id', label: 'name', children: 'sub' }" placeholder="フィールドエイリアス" />
</template>
vue
<script>
export default {
  data() {
    return {
      demoCascFullPath: ['zhejiang', 'hangzhou', 'xihu'],
      demoCascAllLevels: ['zhejiang', 'hangzhou', 'xihu'],
      demoCascSep: ['zhejiang', 'hangzhou', 'xihu'],
      demoCascEmit: ['xihu'],
      demoCascStrict: ['zhejiang', 'hangzhou'],
      demoCascFilter: [],
      demoCascCollapse: ['xihu', 'haishu'],
      demoCascLoose: ['xihu', 'binjiang'],
      demoCascItem: ['zhejiang', 'hangzhou', 'xihu'],
      pathOptions: [
        {
          value: 'zhejiang',
          label: '浙江省',
          children: [
            {
              value: 'hangzhou',
              label: '杭州市',
              children: [
                { value: 'xihu', label: '西湖区' },
                { value: 'binjiang', label: '浜江区' },
              ],
            },
            {
              value: 'ningbo',
              label: '寧波市',
              children: [{ value: 'haishu', label: '海曙区' }],
            },
          ],
        },
        {
          value: 'jiangsu',
          label: '江蘇省',
          children: [
            {
              value: 'nanjing',
              label: '南京市',
              children: [{ value: 'xuanwu', label: '玄武区' }],
            },
          ],
        },
      ],
      aliasedOptions: [
        {
          id: 'zhejiang',
          name: '浙江省',
          sub: [
            {
              id: 'hangzhou',
              name: '杭州市',
              sub: [
                { id: 'xihu', name: '西湖区' },
                { id: 'binjiang', name: '浜江区' },
              ],
            },
            {
              id: 'ningbo',
              name: '寧波市',
              sub: [{ id: 'haishu', name: '海曙区' }],
            },
          ],
        },
      ],
    }
  },
}
</script>

<template>
  <!-- 完全なパス(デフォルト) -->
  <lh-cascader v-model="demoCascFullPath" :options="pathOptions" placeholder="完全なパス(デフォルト)" />
  <!-- 末尾のみ表示 -->
  <lh-cascader v-model="demoCascAllLevels" :options="pathOptions" :show-all-levels="false" placeholder="末尾のみ表示" />
  <!-- 区切り文字 > -->
  <lh-cascader v-model="demoCascSep" :options="pathOptions" separator=" > " placeholder="区切り文字 >" />
  <!-- 末尾の値のみ返す -->
  <lh-cascader v-model="demoCascEmit" :options="pathOptions" :emit-path="false" placeholder="末尾の値のみ返す" />
  <!-- 任意の階層を選択可能 -->
  <lh-cascader v-model="demoCascStrict" :options="pathOptions" check-strictly placeholder="任意の階層を選択可能" />
  <!-- 検索可能 -->
  <lh-cascader v-model="demoCascFilter" :options="pathOptions" filterable placeholder="検索可能" />
  <!-- 複数選択のタグ折りたたみ -->
  <lh-cascader v-model="demoCascCollapse" :options="pathOptions" multiple collapse-tags placeholder="複数選択のタグ折りたたみ" />
  <!-- 親子で連動しない -->
  <lh-cascader v-model="demoCascLoose" :options="pathOptions" multiple :cascading="false" placeholder="親子で連動しない" />
  <!-- フィールドエイリアス -->
  <lh-cascader v-model="demoCascItem" :options="aliasedOptions" :item-config="{ value: 'id', label: 'name', children: 'sub' }" placeholder="フィールドエイリアス" />
</template>

Props ​

プロパティ説明型デフォルト値
modelValueバインド値(string | number)[]() => []
optionsオプションのリスト[LhCascaderNode](#type-LhCascaderNode)[]() => []
sizeサイズ"small" | "medium" | "large" | "mini" | "x-large"'medium'
disabled無効にするかどうかbooleanfalse
clearableクリア可能にするかどうかbooleantrue
placeholderプレースホルダー(未指定時は言語パック cascader.placeholder。中国語では「请选择」)string''
readonly読み取り専用にするかどうかbooleanfalse
showAllLevels入力ボックスに完全なパスを表示するかどうかbooleantrue
checkStrictly任意の階層のノードを選択可能にするかどうかbooleanfalse
emitPath返り値に完全なパスを含めるかどうかbooleantrue
multiple複数選択にするかどうかbooleanfalse
cascading親子で連動させるかどうかbooleantrue
separator区切り文字string'/'
collapseTags複数選択モードでタグを折りたたむかどうかbooleanfalse
filterable検索可能にするかどうかbooleanfalse
itemConfigノードのフィールドエイリアス[LhCascaderItemConfig](#type-LhCascaderItemConfig)() => ({})
sxクイックレイアウトプロパティ(例: { mt: 2, w: '50%' })。インラインスタイルに変換されてトリガーのルート要素に適用されます(ポップアップパネルには影響しません)LhSxProps—

Events ​

イベント名説明コールバック
change選択値が変化したときに発火します(value: (string | number)[], path: LhCascaderNode[] | null)
update:model-valueバインド値が変化したときに発火しますvalue: (string | number)[]

データ構造 ​

LhCascaderNode の型定義:

ts
interface LhCascaderNode {
  value: string | number
  label: string
  disabled?: boolean
  leaf?: boolean
  children?: LhCascaderNode[]
}

型定義 ​

このコンポーネントが外部にエクスポートする TypeScript の型構造を以下に示します(packages/components/cascader/src/types.ts および @lh-ui/share/core/* のソースから自動抽出。各エントリーをクリックすると完全な定義が表示されます。プロパティの説明は上の Props 表を参照してください):

LhCascaderProps
ts
export interface LhCascaderProps {
  modelValue?: (string | number)[]
  options?: LhCascaderNode[]
  size?: LhComponentSize
  disabled?: boolean
  clearable?: boolean
  placeholder?: string
  readonly?: boolean
  showAllLevels?: boolean
  checkStrictly?: boolean
  emitPath?: boolean
  multiple?: boolean
  cascading?: boolean
  separator?: string
  collapseTags?: boolean
  filterable?: boolean
  itemConfig?: LhCascaderItemConfig
  /** sx クイックレイアウトプロパティ */
  sx?: LhSxProps
}
LhCascaderItemConfig (@lh-ui/share/core/cascader より)
ts
/**
 * Cascader props の item 属性のマッピング
 */
export interface LhCascaderItemConfig {
  value?: string
  label?: string
  children?: string
  disabled?: string
  leaf?: string
}
LhCascaderNode (@lh-ui/share/core/cascader より)
ts
/**
 * Cascader ノード
 */
export interface LhCascaderNode {
  value: string | number
  label: string
  disabled?: boolean
  leaf?: boolean
  children?: LhCascaderNode[]
}
LhComponentSize (@lh-ui/share/core/shared より)
ts
export type LhComponentSize = (typeof LH_SIZE_CONST)[keyof typeof LH_SIZE_CONST]

Slots ​

スロット説明デフォルト内容
no-matchフィルターの一致結果がないときに検索パネルに表示するカスタム内容言語パック cascader.noMatch(中国語では「无匹配数据」)

国風の美で、コードの基を築く