Select 드롭다운 선택 박스
여러 옵션 가운데 원하는 항목을 골라 담는 드롭다운 선택 박스 컴포넌트예요.
출처: 문서
본문
언제 사용하나요
사용자가 여러 옵션에서 한 개 또는 몇 개를 선택할 때 사용해요. 시스템이 제공하는 옵션만 드롭다운에서 골라 검색할 수 있고, 직접 입력은 지원하지 않아요.
기본 사용법
size의 sm, md(기본값), lg로 Select 크기를 정하고, overview의 underlined로 아래 테두리만 있는 스타일을 만들 수 있어요.
:::demo
<template>
<div>
<div class="mb-0">Small</div>
<d-select class="mb-2" v-model="value1" :options="options" size="sm"></d-select>
<div class="mb-0">Middle</div>
<d-select class="mb-2" v-model="value2" :options="options"></d-select>
<div class="mb-0">Large</div>
<d-select class="mb-2" v-model="value3" :options="options" size="lg"></d-select>
<div class="mb-0">Underlined</div>
<d-select class="mb-2" v-model="value4" :options="options" size="lg" overview="underlined"></d-select>
</div>
</template>
<script>
import { defineComponent, reactive, ref } from 'vue';
export default defineComponent({
setup() {
const value1 = ref('');
const value2 = ref('');
const value3 = ref('');
const value4 = ref('');
const items = new Array(6).fill(0).map((item, i) => `Option ${i + 1}`);
const options = reactive(items);
return {
value1,
value2,
value3,
value4,
options,
};
},
});
</script>
:::
다중 선택
multiple을 true로 하면 다중 선택이 켜지고, multiple-limit으로 선택할 수 있는 개수를 제한할 수 있어요.
:::demo
<template>
<div class="mb-0">基础多选</div>
<d-select class="mb-2" v-model="value1" :options="options" :multiple="true" :multiple-limit="2" />
<div class="mb-0">collapse-tags</div>
<d-select class="mb-2" v-model="value2" :options="options" :multiple="true" :collapse-tags="true" />
<div class="mb-0">collapse-tags-tooltip</div>
<d-select class="mb-2" v-model="value3" :options="options" :multiple="true" :collapse-tags="true" :collapse-tags-tooltip="true" />
</template>
<script>
import { defineComponent, reactive, ref } from 'vue';
export default defineComponent({
setup() {
const value1 = ref([]);
const value2 = ref([]);
const value3 = ref([]);
const items = new Array(6).fill(0).map((item, i) => `Option ${i + 1}`);
const options = reactive(items);
return {
value1,
value2,
value3,
options,
};
},
});
</script>
:::
비활성화
disabled를 true로 하면 Select 전체가 비활성화되고, option-disabled-key로 개별 옵션을 비활성화할 수 있어요. 예를 들어 disabled 필드를 지정하면 객체의 disabled가 true일 때 그 옵션은 선택할 수 없어요.
:::demo
<template>
<d-select class="mb-2" v-model="value1" :options="options1" :disabled="true" />
<d-select class="mb-2" v-model="value2" :options="options2" option-disabled-key="disabled" />
<d-select class="mb-2" v-model="value3" :options="options3" :multiple="true" option-disabled-key="notAllow" />
</template>
<script>
import { defineComponent, reactive, ref } from 'vue';
export default defineComponent({
setup() {
const value1 = ref('');
const value2 = ref('');
const value3 = ref([]);
const items = new Array(6).fill(0).map((item, i) => `Option ${i + 1}`);
const options1 = reactive(items);
const options2 = reactive([
{
name: 'Option 1',
value: 0,
},
{
name: 'Option 2',
value: 1,
},
{
name: 'Option 3',
value: 2,
disabled: true,
},
]);
const options3 = reactive([
{
name: 'Option 1',
value: 0,
},
{
name: 'Option 2',
value: 1,
notAllow: true,
},
{
name: 'Option 3',
value: 2,
},
]);
return {
value1,
value2,
value3,
options1,
options2,
options3,
};
},
});
</script>
:::
선택값 비우기 가능
allow-clear를 true로 설정하면 Select의 선택값을 비울 수 있어요.
:::demo
<template>
<d-select class="mb-2" v-model="value1" :options="options" :allow-clear="true" />
<d-select v-model="value2" :options="options" :multiple="true" :allow-clear="true" />
</template>
<script>
import { defineComponent, reactive, ref } from 'vue';
export default defineComponent({
setup() {
const value1 = ref('');
const value2 = ref([]);
const items = new Array(6).fill(0).map((item, i) => `Option ${i + 1}`);
const options = reactive(items);
return {
value1,
value2,
options,
};
},
});
</script>
:::
드롭다운 목록 표시/숨김 메서드
toggleChange 메서드를 사용하면 코드에서 드롭다운 목록을 보이거나 숨길 수 있어요.
:::demo
<template>
<div>
<d-button @click.stop="toggleChange" @pointerup.stop="() => {}" class="mb-2">展开 / 隐藏</d-button>
<d-select ref="demoSelect" v-model="toggleValue" :options="options" @load-more="loadMore"></d-select>
</div>
</template>
<script>
import { defineComponent, reactive, ref } from 'vue';
export default defineComponent({
setup() {
const toggleValue = ref('');
const visitable = ref(false);
const items = new Array(12).fill(0).map((item, i) => `Option ${i + 1}`);
const options = reactive(items);
const newItems = new Array(2).fill(0).map((item, i) => `Option new`);
const demoSelect = ref(null);
const toggleChange = () => {
visitable.value = !visitable.value;
demoSelect.value.toggleChange(visitable.value);
};
const loadMore = () => {
if (options.length <= 20) {
options.push(...newItems);
console.log('load more');
}
};
return {
toggleValue,
options,
demoSelect,
toggleChange,
loadMore,
};
},
});
</script>
:::
드롭다운 패널 표시 직접 만들기
d-option으로 개별 내용을 구성해요.
:::demo
<template>
<div class="mb-0">d-option</div>
<d-select class="mb-2" v-model="value1" :allow-clear="true">
<d-option v-for="(item, index) in options.data" :key="index" :value="item.value" :name="item.name"></d-option>
</d-select>
<div class="mb-0">d-option自定义内容及样式</div>
<d-select class="mb-2" v-model="value2" :allow-clear="true">
<d-option v-for="(item, index) in options1.data" :key="index" :value="item">
<div class="clear-float">
<span style="float: left;">{{ item }}</span>
<span style="float: right;">{{ index + 1 }}</span>
</div>
</d-option>
</d-select>
</template>
<script>
import { defineComponent, reactive, ref } from 'vue';
export default defineComponent({
setup() {
const value1 = ref('');
const value2 = ref('');
const items = new Array(6).fill(0).map((item, i) => {
return {
value: `Option ${i + 1}`,
name: `Option ${i + 1}`,
};
});
const items1 = new Array(6).fill(0).map((item, i) => `Option ${i + 1}`);
const options = reactive({
data: items,
});
const options1 = reactive({
data: items1,
});
return {
value1,
value2,
options,
options1,
};
},
});
</script>
<style>
.clear-float:after {
content: '';
display: block;
height: 0;
clear: both;
}
</style>
:::
옵션 그룹으로 묶기
d-option-group으로 옵션을 그룹으로 묶어요. label 속성이 그룹 이름이 돼요.
:::demo
<template>
<d-select v-model="groupValue" :allow-clear="true" class="select-option-group">
<d-option-group label="分组一">
<d-option v-for="(item, index) in options1.data" :key="index" :value="item.value" :name="item.name"></d-option>
</d-option-group>
<d-option-group label="分组二" :disabled="true">
<d-option v-for="(item, index) in options2.data" :key="index" :value="item.value" :name="item.name"></d-option>
</d-option-group>
</d-select>
</template>
<script>
import { defineComponent, reactive, ref } from 'vue';
export default defineComponent({
setup() {
const groupValue = ref('');
const items = new Array(6).fill(0).map((item, i) => {
return {
value: `Option ${i + 1}`,
name: `Option ${i + 1}`,
};
});
const items1 = new Array(6).fill(0).map((item, i) => {
return {
value: `Test ${i + 1}`,
name: `Test ${i + 1}`,
};
});
const options1 = reactive({
data: items,
});
const options2 = reactive({
data: items1,
});
return {
groupValue,
options1,
options2,
};
},
});
</script>
<style>
.select-option-group {
ul {
padding: 0;
li {
list-style-type: none;
}
}
}
</style>
:::
필터, 옵션 검색
필터·검색 기능을 활용하면 옵션을 빠르게 찾을 수 있어요.
filter 속성을 추가하면 필터 기능이 켜져요. 값으로 true를 넘기면 기본적으로 name 속성에 입력값이 포함된 옵션을 찾아 줘요.
다른 필터 로직을 쓰고 싶다면 filter에 Function을 넘길 수 있어요. 입력값이 바뀔 때 호출되며 입력값이 인자로 전달돼요.
remote 속성을 추가하면 원격 검색 기능이 켜져요. 원격 검색일 때는 loading 속성과 함께 쓰고, 로딩 중에는 loading-text로 정의한 문구가 표시돼요.
:::demo
<template>
<div class="mb-0">默认筛选</div>
<d-select class="mb-2" v-model="value1" :allow-clear="true" filter @input-change="handleInput">
<d-option v-for="(item, index) in options.data" :key="index" :value="item.value" :name="item.name"></d-option>
</d-select>
<div class="mb-0">远程搜索</div>
<d-select class="mb-2" v-model="value2" :allow-clear="true" :filter="filterFunc" remote placeholder="请输入搜索关键字" :loading="loading">
<d-option v-for="(item, index) in options1.data" :key="index" :value="item.value" :name="item.name"></d-option>
</d-select>
</template>
<script>
import { defineComponent, reactive, ref } from 'vue';
export default defineComponent({
setup() {
const value1 = ref('');
const value2 = ref('');
const loading = ref(false);
const items = new Array(6).fill(0).map((item, i) => {
return {
value: `Option ${i + 1}`,
name: `Option ${i + 1}`,
};
});
const options = reactive({
data: items,
});
const options1 = reactive({
data: [],
});
const filterFunc = (query) => {
if (query) {
loading.value = true;
setTimeout(() => {
options1.data = items.filter((item) => {
return item.name.toLowerCase().includes(query.toLowerCase());
});
loading.value = false;
}, 200);
} else {
options1.data = [];
}
};
const handleInput = (val) => {
console.log(val);
};
return {
value1,
value2,
options,
options1,
loading,
filterFunc,
handleInput,
};
},
});
</script>
:::
옵션 직접 추가하기
allow-create 속성을 추가하면 새 옵션을 만드는 기능이 켜져요. allow-create가 제대로 동작하려면 filter 값이 반드시 true여야 해요.
:::demo
<template>
<d-select v-model="value" :options="options" :allow-clear="true" multiple filter allow-create> </d-select>
</template>
<script>
import { defineComponent, reactive, ref } from 'vue';
export default defineComponent({
setup() {
const value = ref([]);
const list = new Array(6).fill(0).map((item, i) => `Option ${i + 1}`);
const options = reactive(list);
return {
value,
options,
};
},
});
</script>
:::
원격으로 데이터 불러오기
:::demo
<template>
<d-select v-model="value" :options="options.data" :allow-clear="true" :loading="loading" @toggleChange="toggleChange"></d-select>
</template>
<script>
import { defineComponent, reactive, ref } from 'vue';
export default defineComponent({
setup() {
const value = ref([]);
const list = new Array(6).fill(0).map((item, i) => `Option ${i + 1}`);
const options = reactive({
data: [],
});
const loading = ref(false);
const toggleChange = (bool) => {
if (bool) {
loading.value = true;
setTimeout(() => {
options.data = list;
loading.value = false;
}, 3000);
}
};
return {
value,
options,
loading,
toggleChange,
};
},
});
</script>
:::
Select 파라미터
| 파라미터 | 타입 | 기본값 | 설명 | Demo 링크 |
|---|---|---|---|---|
| options | array |
[] | 선택, option 하위 컴포넌트 사용과 상호 배타적이에요. 둘 중 하나는 반드시 있고, 둘 다 있으면 안 돼요 | 기본 사용법 |
| multiple | boolean |
false | 선택, 다중 선택을 지원할지 여부예요 | 다중 선택 |
| size | string |
'md' | 선택, 드롭다운 선택 박스 크기예요. 'lg', 'md', 'sm' 세 가지를 고를 수 있어요 | 기본 사용법 |
| disabled | boolean |
false | 선택, 드롭다운을 비활성화할지 여부예요 | 비활성화 |
| placeholder | string |
'선택하세요' | 선택, 입력창의 placeholder예요 | |
| overview | string |
'border' | 선택, 선택 박스 스타일을 정해요. 기본은 테두리가 있는 'border', 'underlined' | 기본 사용법 |
| option-disabled-key | string |
'' | 선택, 개별 옵션 비활성화; options 자원을 Object로 넘길 때, 예를 들어 'disabled'로 설정하면 객체의 disabled 속성이 true일 때 해당 옵션이 비활성화돼요; ''로 설정하면 개별 옵션을 비활성화하지 않아요 |
비활성화 |
| allow-clear | boolean |
false | 선택, 선택값을 비울 수 있는지 설정해요. 단일 선택 시나리오에서만 동작해요 | 선택값 비우기 가능 |
| collapse-tags | boolean |
false | 선택, 선택한 항목들을 개수 표시로 합칠 수 있는지 설정해요 | 다중 선택 |
| collapse-tags-tooltip | boolean |
false | 선택, 접힌 글자 위에 마우스를 올렸을 때 구체적인 선택값을 보여줄지 설정해요 | 다중 선택 |
| filter | boolean | function |
false | 선택, 필터 기능을 켤지 설정해요. 함수로 설정하면 커스텀 검색 필터 메서드가 돼요 | 필터, 옵션 검색 |
| remote | boolean |
false | 선택, 원격 검색을 사용할지 설정해요. filter 함수와 함께 사용해요 | 필터, 옵션 검색 |
| allow-create | boolean |
false | 선택, 새 옵션 추가 기능을 사용할지 설정해요. filter가 true일 때 함께 사용해요 | 옵션 직접 추가하기 |
| no-data-text | string |
'데이터 없음' | 선택, 옵션이 없을 때 표시할 문구예요. empty 슬롯으로도 직접 만들 수 있어요 | 필터, 옵션 검색 |
| no-match-text | string |
'관련 기록을 찾을 수 없음' | 선택, 검색 조건에 일치하는 항목이 없을 때 표시할 문구예요. empty 슬롯으로도 직접 만들 수 있어요 | 필터, 옵션 검색 |
| loading | boolean |
false | 선택, 드롭다운 옵션을 원격으로 불러올지 설정해요. loading-text와 함께 사용해요 | 원격으로 데이터 불러오기 |
| loading-text | string |
'로딩 중' | 선택, 원격 검색 시 표시할 문구예요 | 원격으로 데이터 불러오기 |
| multiple-limit | number |
'0' | 선택, multiple 속성이 true일 때 동작해요. 사용자가 최대로 선택할 수 있는 항목 수이고, 0이면 제한이 없어요 | 다중 선택 |
| show-glow-style | boolean |
true | 선택, 마우스를 올릴 때의 발광 효과를 표시할지 여부예요 | |
| menu-class | string |
'' | 선택, 드롭다운 메뉴의 스타일 클래스 이름을 직접 정해요 | |
| max-length | number |
-- | 선택, 필터링할 때 입력창에 입력할 수 있는 최대 길이예요 | |
| append-to-body | boolean |
true | 선택, 드롭다운 메뉴를 body에 append할지 여부예요 |
Select 이벤트
| 이벤트명 | 타입 | 설명 | Demo 링크 |
|---|---|---|---|
| value-change | Function(data) |
선택, 선택값이 바뀔 때 발생해요. 인자로 현재 선택된 값을 넘겨줘요 (다중 선택일 때는 배열) | |
| toggle-change | Function(boolean) |
선택, 드롭다운이 열리고 닫히는 toggle 이벤트예요 | |
| focus | Function(e: FocusEvent) |
선택, 포커스를 얻을 때 발생해요 | |
| blur | Function(e: FocusEvent) |
선택, 포커스를 잃을 때 발생해요 | |
| clear | Function() |
선택, 오른쪽 삭제 아이콘으로 모든 옵션을 비울 때 발생해요 | |
| remove-tag | Function(value) |
선택, 다중 선택에서 tag 하나를 삭제할 때 발생해요. 인자는 해당 tag의 값이에요 | |
| load-more | Function() |
선택, 드롭다운에 스크롤바가 있을 때 맨 아래까지 스크롤하면 발생해요 | 드롭다운 목록 표시/숨김 메서드 |
| input-change | Function(value) |
선택, 입력창에 내용을 입력할 때 발생해요. 인자는 입력된 값이에요 | 필터, 옵션 검색 |
Select 슬롯
| 이름 | 설명 |
|---|---|
| default | Select 드롭다운 패널 내용을 직접 만들어요 (OptionGroup/ Option) |
| empty | 옵션이 없을 때 드롭다운 패널 내용을 직접 만들어요 |
Select 메서드
| 이름 | 설명 | Demo 링크 |
|---|---|---|
| focus | 선택기 입력창이 포커스를 얻게 해요 | - |
| blur | 선택기 입력창이 포커스를 잃게 해요 | - |
| toggleChange | 선택기 드롭다운 목록을 표시/숨김해요 | 드롭다운 목록 표시/숨김 메서드 |
OptionGroup 파라미터
| 파라미터 | 타입 | 기본값 | 설명 | Demo 링크 |
|---|---|---|---|---|
| label | string |
'' | 선택, 그룹의 이름이에요 | 옵션 그룹으로 묶기 |
| disabled | boolean |
false | 선택, 해당 그룹 아래 모든 옵션을 비활성화할지 여부예요 | 옵션 그룹으로 묶기 |
OptionGroup 슬롯
| 이름 | 설명 |
|---|---|
| default | 개별 옵션의 표시 내용을 직접 만들어요 (Option) |
Option 파라미터
| 파라미터 | 타입 | 기본값 | 설명 | Demo 링크 |
|---|---|---|---|---|
| value | string | number |
'' | 필수, 옵션의 고유 식별자예요 | 드롭다운 패널 표시 직접 만들기 |
| name | string |
'' | 선택, 옵션에 표시할 내용이에요 | 드롭다운 패널 표시 직접 만들기 |
| disabled | boolean |
false | 선택, 개별 옵션을 비활성화해요 | 드롭다운 패널 표시 직접 만들기 |
Option 슬롯
| 이름 | 설명 |
|---|---|
| default | 개별 옵션의 표시 내용을 직접 만들어요 |
더 알아보기 (Learn more)
d-select는 크기 조절부터 다중 선택, 필터·원격 검색, 옵션 그룹까지 드롭다운에 필요한 기능을 두루 갖추고 있어요. 데모를 위에서부터 차례로 따라 하다 보면 각 속성의 역할이 자연스럽게 익숙해질 거예요.