Cascader 캐스케이더
계층 구조로 된 데이터를 단계별로 골라서 선택할 수 있는 드롭다운 캐스케이더 컴포넌트예요.
출처: 문서
본문
언제 사용하나요
- 시/도/구, 회사 조직 계층, 상품 분류처럼 서로 연관된 데이터 집합에서 선택이 필요할 때 사용해요.
- 큰 데이터 집합에서 선택할 때 여러 단계의 분류로 나눠 두면 선택하기 한결 편해요.
기본 사용법
:::demo
<template>
<div class="mb-0">hover mode</div>
<d-cascader class="mb-2" :options="options" placeholder="请选择" style="width: 200px"></d-cascader>
<div class="mb-0">click mode</div>
<d-cascader class="mb-2" :options="options" v-model="value" showPath trigger="click" placeholder="请选择" style="width: 200px"></d-cascader>
<div class="mb-0">data empty</div>
<d-cascader class="mb-2" :options="[]" trigger="click" placeholder="请选择" style="width: 200px"></d-cascader>
<div class="mb-0">disabled</div>
<d-cascader class="mb-2" :options="[]" disabled trigger="click" placeholder="请选择" style="width: 200px"></d-cascader>
</template>
<script>
import { defineComponent, reactive, ref } from 'vue';
export default defineComponent({
setup() {
const options = reactive([
{
label: 'option1',
value: 1,
children: [
{
label: 'option1-1',
value: 4,
children: [
{
label: 'option1-1-1',
value: 8,
children: [],
},
{
label: 'option1-1-2',
value: 9,
children: [
{
label: 'option1-1-2-1',
value: 81,
},
],
},
],
},
{
label: 'option1-2',
value: 41,
},
{
label: 'option1-3',
value: 42,
},
{
label: 'option1-4',
value: 43,
},
],
},
{
label: 'option2',
value: 2,
children: [
{
label: 'option2-1',
value: 5,
children: [
{
label: 'option2-1-1',
value: 51,
},
{
label: 'option2-1-2',
value: 61,
disabled: true,
},
],
},
{
label: 'option2-2',
value: 6,
children: [
{
label: 'option2-2-1',
value: 512,
},
{
label: 'option2-2-2',
value: 611,
},
],
},
{
label: 'option2-3',
value: 712,
},
],
},
{
label: 'option3',
value: 3,
children: [],
disabled: true,
},
]);
const value = ref([1, 4, 9, 81]);
return { options, value };
},
});
</script>
:::
크기
:::demo sm, md, lg 세 가지 크기를 지원하며, 기본값은 md예요.
<template>
<h4>Small</h4>
<d-cascader :options="options" size="sm" placeholder="请选择" style="width: 200px"></d-cascader>
<h4>Middle</h4>
<d-cascader :options="options" size="md" placeholder="请选择" style="width: 200px"></d-cascader>
<h4>Large</h4>
<d-cascader :options="options" size="lg" placeholder="请选择" style="width: 200px"></d-cascader>
</template>
<script>
import { defineComponent, reactive, ref } from 'vue';
export default defineComponent({
setup() {
const options = reactive([
{
label: 'option1',
value: 1,
children: [
{
label: 'option1-1',
value: 4,
children: [
{
label: 'option1-1-1',
value: 8,
children: [],
},
{
label: 'option1-1-2',
value: 9,
children: [
{
label: 'option1-1-2-1',
value: 81,
},
],
},
],
},
{
label: 'option1-2',
value: 41,
},
{
label: 'option1-3',
value: 42,
},
{
label: 'option1-4',
value: 43,
},
],
},
{
label: 'option2',
value: 2,
children: [
{
label: 'option2-1',
value: 5,
children: [
{
label: 'option2-1-1',
value: 51,
},
{
label: 'option2-1-2',
value: 61,
disabled: true,
},
],
},
{
label: 'option2-2',
value: 6,
children: [
{
label: 'option2-2-1',
value: 512,
},
{
label: 'option2-2-2',
value: 611,
},
],
},
{
label: 'option2-3',
value: 712,
},
],
},
{
label: 'option3',
value: 3,
children: [],
disabled: true,
},
]);
const value = ref([1, 4, 9, 81]);
return { options, value };
},
});
</script>
:::
호스트 엘리먼트 커스터마이즈
:::demo host 슬롯으로 Cascader 메뉴를 펼칠 호스트 엘리먼트를 직접 정의할 수 있어요.
<template>
<d-cascader class="mb-2" v-model="value" :options="options" width="fit-content">
<template #host>
<d-button>请选择</d-button>
</template>
</d-cascader>
<div>选择的value值:{{ value }}</div>
</template>
<script>
import { defineComponent, reactive, ref } from 'vue';
export default defineComponent({
setup() {
const options = reactive([
{
label: 'option1',
value: 1,
children: [
{
label: 'option1-1',
value: 4,
children: [
{
label: 'option1-1-1',
value: 8,
children: [],
},
{
label: 'option1-1-2',
value: 9,
children: [
{
label: 'option1-1-2-1',
value: 81,
},
],
},
],
},
{
label: 'option1-2',
value: 41,
},
{
label: 'option1-3',
value: 42,
},
{
label: 'option1-4',
value: 43,
},
],
},
{
label: 'option2',
value: 2,
children: [
{
label: 'option2-1',
value: 5,
children: [
{
label: 'option2-1-1',
value: 51,
},
{
label: 'option2-1-2',
value: 61,
disabled: true,
},
],
},
{
label: 'option2-2',
value: 6,
children: [
{
label: 'option2-2-1',
value: 512,
},
{
label: 'option2-2-2',
value: 611,
},
],
},
{
label: 'option2-3',
value: 712,
},
],
},
{
label: 'option3',
value: 3,
children: [],
disabled: true,
},
]);
const value = ref();
return { value, options };
},
});
</script>
:::
검색 기능
:::demo
<template>
<d-cascader
:options="options"
v-model="value1"
placeholder="请选择"
trigger="click"
:width="300"
filterable
:debounce="500"
:before-filter="beforeFilter"
@change="changeFun"
class="mb-2"
></d-cascader>
<div>选择的value值:{{ value1 }}</div>
</template>
<script>
import { defineComponent, reactive, ref } from 'vue';
export default defineComponent({
setup() {
const options = reactive([
{
label: 'option1',
value: 1,
children: [
{
label: 'option1-1',
value: 4,
children: [
{
label: 'option1-1-1',
value: 8,
children: [],
},
{
label: 'option1-1-2',
value: 9,
children: [
{
label: 'option1-1-2-1',
value: 81,
},
],
},
],
},
{
label: 'option1-2',
value: 41,
},
{
label: 'option1-3',
value: 42,
},
{
label: 'option1-4',
value: 43,
},
],
icon: 'folder',
},
{
label: 'option2',
value: 2,
children: [
{
label: 'option2-1',
value: 5,
children: [
{
label: 'option2-1-1',
value: 51,
},
{
label: 'option2-1-2',
value: 61,
disabled: true,
},
],
},
{
label: 'option2-2',
value: 6,
children: [
{
label: 'option2-2-1',
value: 512,
},
{
label: 'option2-2-2',
value: 611,
},
],
},
{
label: 'option2-3',
value: 712,
},
],
icon: 'folder',
},
{
label: 'option3',
value: 3,
children: [],
disabled: true,
icon: 'folder',
},
]);
const value1 = ref([1, 4, 8]);
const beforeFilter = (val) => {
return new Promise((resolve, reject) => {
resolve();
});
};
const changeFun = (value) => {
console.log(value);
};
return {
options,
value1,
beforeFilter,
changeFun,
};
},
});
</script>
:::
API
| 파라미터 | 타입 | 기본값 | 설명 | Demo 링크 |
|---|---|---|---|---|
| v-model | (number|string)[] |
[] | 선택, 단일 선택 시 `(number\ | sring)[]` |
| trigger | 'hover'|'click' |
'hover' | 선택, 하위 메뉴 펼침 방식 지정 | 기본 사용법 |
| options | CascaderItem[] |
[] | 필수, 캐스케이더 메뉴 정보 | 기본 사용법 |
| placeholder | string |
'' | 선택, 미선택 시 입력창 표시 정보 | 기본 사용법 |
| disabled | boolean |
false | 선택, 캐스케이더 비활성화 여부 | 기본 사용법 |
| width | number | string |
200 | 선택, 단위 px. 컴포넌트 입력창 너비와 드롭다운 너비 제어 | 기본 사용법 |
| dropdownWidth | number | string |
200 | 선택, 단위 px. 드롭다운 리스트 너비 제어, 기본값은 컴포넌트 입력창 width와 동일 | 기본 사용법 |
| clearable | boolean |
true | 선택, 옵션 비우기 지원 여부 | 기본 사용법 |
| filterable | boolean |
true | 선택, 옵션 검색 가능 여부 | 검색 가능 |
| debounce | number |
300 | 선택, 검색 키워드 입력 디바운스 지연 | 검색 가능 |
| before-filter | function(value) |
-- | 선택, 필터 함수 호출 전 훅 함수. 이 함수가 false를 반환하거나 reject된 Promise이면 이후 필터 로직은 실행되지 않음 | 검색 가능 |
| size | CascaderSize | 'md' | 텍스트 입력창 크기 | 크기 |
Cascader 이벤트
| 이벤트 | 설명 | 콜백 파라미터 |
|---|---|---|
| change | 바인딩 값 변경 시 트리거되는 이벤트 | Function(value) |
| blur | 포커스 상실 시 트리거 | Function(e: FocusEvent) |
| focus | 포커스 획득 시 트리거 | Function(e: FocusEvent) |
Cascader 슬롯
| 슬롯명 | 설명 |
|---|---|
| host | 캐스케이드 메뉴를 펼칠 호스트 요소 커스텀 |
인터페이스 & 타입 정의
CascaderItem
interface CascaderItem {
label: string;
value: number | string;
children?: CascaderItem[];
disabled?: boolean;
icon?: string;
}
CascaderSize
type CascaderSize = 'sm' | 'md' | 'lg';
더 알아보기 (Learn more)
options에 계층 구조 데이터를 담아 시/도/구 같은 연관 데이터를 단계별로 선택할 수 있어요. 자세한 내용은 DevUI 공식 문서를 참고해 보세요.