Select (선택)
Select (선택)
옵션이 많을 때 드롭다운 메뉴를 사용해서 원하는 옵션을 표시하고 선택하는 컴포넌트예요.
출처: 문서
본문
TIP 2.5.0 버전 이후
el-select의 기본 너비는 100%로 바뀌었어요. 인라인 폼에서 사용하면 너비가 접혀버려요. 너비를 제대로 표시하려면el-select에 특정 너비를 지정해야 해요 (예: Example).
기본 사용법 (Basic usage)
v-model은 현재 선택된 el-option의 값이에요.
Options 속성 (Options attribute) 2.10.5
기본 el-option 사용법의 단축형이에요. props 속성으로 옵션의 별칭을 커스터마이징할 수 있어요.
비활성 옵션 (Disabled option)
el-option에서 disabled 값을 true로 설정해서 이 옵션을 비활성화해요.
Select 비활성화 (Disabled select)
전체 컴포넌트를 비활성화해요. el-select의 disabled를 설정해서 비활성화해요.
지우기 가능 (Clearable)
지우기 아이콘으로 Select를 지울 수 있어요. el-select에 clearable 속성을 설정하면 지우기 아이콘이 나타나요.
크기 (Sizes)
size 속성을 추가해서 Select의 크기를 바꿔요. 기본 크기 외에 두 가지 옵션이 더 있어요: large, small.
import { ref } from 'vue'
const value = ref('')
const options = [
{
value: 'Option1',
label: 'Option1',
},
{
value: 'Option2',
label: 'Option2',
},
{
value: 'Option3',
label: 'Option3',
},
{
value: 'Option4',
label: 'Option4',
},
{
value: 'Option5',
label: 'Option5',
},
]
기본 다중 선택 (Basic multiple select)
다중 선택은 태그로 선택된 옵션을 표시해요. el-select에 multiple 속성을 설정해서 다중 모드를 활성화해요. 이 경우 v-model의 값은 선택된 옵션의 배열이에요. 기본적으로 선택된 옵션은 Tags로 표시돼요. collapse-tags 속성을 사용해서 텍스트로 접을 수 있어요. collapse-tags-tooltip 속성으로 collapse 텍스트 위에 마우스를 올렸을 때 확인할 수 있어요.
import { ref } from 'vue'
const value1 = ref([])
const value2 = ref([])
const value3 = ref([])
const value4 = ref([])
const options = [
{
value: 'Option1',
label: 'Option1',
},
{
value: 'Option2',
label: 'Option2',
},
{
value: 'Option3',
label: 'Option3',
},
{
value: 'Option4',
label: 'Option4',
},
{
value: 'Option5',
label: 'Option5',
},
]
커스텀 템플릿 (Custom template)
옵션의 HTML 템플릿을 커스터마이징할 수 있어요. el-option의 슬롯에 커스텀 HTML 템플릿을 넣어요.
드롭다운 헤더 (Header of the dropdown) 2.4.3
드롭다운의 헤더를 커스터마이징할 수 있어요. 슬롯으로 내용을 커스터마이징해요.
드롭다운 푸터 (Footer of the dropdown) 2.4.3
드롭다운의 푸터를 커스터마이징할 수 있어요. 슬롯으로 내용을 커스터마이징해요.
그룹화 (Grouping)
옵션을 그룹으로 표시해요. el-option-group을 사용해서 옵션을 그룹화하고, 그 label 속성이 그룹의 이름을 나타내요.
옵션 필터링 (Option filtering)
원하는 옵션을 필터링할 수 있어요. el-select에 filterable을 추가하면 필터링이 활성화돼요. 기본적으로 Select는 label 속성이 입력 값을 포함하는 모든 옵션을 찾아요. 다른 필터링 전략을 선호하면 filter-method를 전달할 수 있어요. filter-method는 입력 값이 변경될 때 호출되는 Function이고, 매개변수는 현재 입력 값이에요.
원격 검색 (Remote Search)
키워드를 입력하고 서버에서 데이터를 검색해요. filterable과 remote의 값을 true로 설정해서 원격 검색을 활성화하고, remote-method를 전달해야 해요. remote-method는 입력 값이 변경될 때 호출되는 Function이고, 매개변수는 현재 입력 값이에요. el-option이 v-for 디렉티브로 렌더링된다면 el-option에 key 속성을 추가해야 한다는 점에 유의하세요. 그 값은 유일해야 하고, 아래 예제처럼 item.value를 사용할 수 있어요.
import { onMounted, ref } from 'vue'
interface ListItem {
value: string
label: string
}
const list = ref([])
const options = ref([])
const value = ref([])
const loading = ref(false)
onMounted(() => {
list.value = states.map((item) => {
return { value: `value:${item}`, label: `label:${item}` }
})
})
const remoteMethod = (query: string) => {
if (query) {
loading.value = true
setTimeout(() => {
loading.value = false
options.value = list.value.filter((item) => {
return item.label.toLowerCase().includes(query.toLowerCase())
})
}, 200)
} else {
options.value = []
}
}
const states = [
'Alabama',
'Alaska',
'Arizona',
'Arkansas',
'California',
'Colorado',
'Connecticut',
'Delaware',
'Florida',
'Georgia',
'Hawaii',
'Idaho',
'Illinois',
'Indiana',
'Iowa',
'Kansas',
'Kentucky',
'Louisiana',
'Maine',
'Maryland',
'Massachusetts',
'Michigan',
'Minnesota',
'Mississippi',
'Missouri',
'Montana',
'Nebraska',
'Nevada',
'New Hampshire',
'New Jersey',
'New Mexico',
'New York',
'North Carolina',
'North Dakota',
'Ohio',
'Oklahoma',
'Oregon',
'Pennsylvania',
'Rhode Island',
'South Carolina',
'South Dakota',
'Tennessee',
'Texas',
'Utah',
'Vermont',
'Virginia',
'Washington',
'West Virginia',
'Wisconsin',
'Wyoming',
]
새 항목 만들기 (Create new items)
select 옵션에 없는 새 항목을 만들고 선택해요. allow-create 속성을 사용하면 사용자가 입력 박스에 입력해서 새 항목을 만들 수 있어요. allow-create가 동작하려면 filterable이 true여야 한다는 점에 유의하세요. 이 예제는 default-first-option도 보여줘요. 이 속성이 true로 설정되면 마우스나 화살표 키로 이동할 필요 없이 Enter 키를 눌러 현재 옵션 목록의 첫 번째 옵션을 선택할 수 있어요.
value-key 속성 사용 (Use value-key attribute)
Select의 바인딩 값이 객체라면 value-key를 고유 식별 키 이름으로 지정해야 해요. value-key 속성을 사용하면 중복 라벨이 있는 데이터를 적절히 처리할 수 있어요. label 속성의 값은 중복되지만, id를 통해 옵션을 식별할 수 있어요.
import { ref } from 'vue'
type Option = {
id: number
label: string
desc: string
}
const value = ref()
const options = ref([
{ id: 1, label: 'Option A', desc: 'Option A - 230506' },
{ id: 2, label: 'Option B', desc: 'Option B - 230506' },
{ id: 3, label: 'Option C', desc: 'Option C - 230506' },
{ id: 4, label: 'Option A', desc: 'Option A - 230507' },
])
커스텀 태그 (Custom Tag) 2.5.0
태그를 커스터마이징할 수 있어요. el-select의 슬롯에 커스텀 태그를 넣어요. collapse-tags, collapse-tags-tooltip, max-collapse-tags는 동작하지 않아요.
import { ref } from 'vue'
const value = ref([])
const colors = [
{
value: '#E63415',
label: 'red',
},
{
value: '#FF6600',
label: 'orange',
},
{
value: '#FFDE0A',
label: 'yellow',
},
{
value: '#1EC79D',
label: 'green',
},
{
value: '#14CCCC',
label: 'cyan',
},
{
value: '#4167F0',
label: 'blue',
},
{
value: '#6222C9',
label: 'purple',
},
]
colors.forEach((color) => {
value.value.push(color.value)
})
.el-tag {
border: none;
aspect-ratio: 1;
}
커스텀 로딩 (Custom Loading) 2.5.2
로딩 내용을 재정의해요.
import { onMounted, ref } from 'vue'
interface ListItem {
value: string
label: string
}
const list = ref([])
const options = ref([])
const value = ref([])
const loading = ref(false)
onMounted(() => {
list.value = states.map((item) => {
return { value: `value:${item}`, label: `label:${item}` }
})
})
const remoteMethod = (query: string) => {
if (query) {
loading.value = true
setTimeout(() => {
loading.value = false
options.value = list.value.filter((item) => {
return item.label.toLowerCase().includes(query.toLowerCase())
})
}, 3000)
} else {
options.value = []
}
}
const states = [
'Alabama',
'Alaska',
'Arizona',
'Arkansas',
'California',
'Colorado',
'Connecticut',
'Delaware',
'Florida',
'Georgia',
'Hawaii',
'Idaho',
'Illinois',
'Indiana',
'Iowa',
'Kansas',
'Kentucky',
'Louisiana',
'Maine',
'Maryland',
'Massachusetts',
'Michigan',
'Minnesota',
'Mississippi',
'Missouri',
'Montana',
'Nebraska',
'Nevada',
'New Hampshire',
'New Jersey',
'New Mexico',
'New York',
'North Carolina',
'North Dakota',
'Ohio',
'Oklahoma',
'Oregon',
'Pennsylvania',
'Rhode Island',
'South Carolina',
'South Dakota',
'Tennessee',
'Texas',
'Utah',
'Vermont',
'Virginia',
'Washington',
'West Virginia',
'Wisconsin',
'Wyoming',
]
.el-select-dropdown__loading {
display: flex;
justify-content: center;
align-items: center;
height: 100px;
font-size: 20px;
}
.circular {
display: inline;
height: 30px;
width: 30px;
animation: loading-rotate 2s linear infinite;
}
.path {
animation: loading-dash 1.5s ease-in-out infinite;
stroke-dasharray: 90, 150;
stroke-dashoffset: 0;
stroke-width: 2;
stroke: var(--el-color-primary);
stroke-linecap: round;
}
.loading-path .dot1 {
transform: translate(3.75px, 3.75px);
fill: var(--el-color-primary);
animation: custom-spin-move 1s infinite linear alternate;
opacity: 0.3;
}
.loading-path .dot2 {
transform: translate(calc(100% - 3.75px), 3.75px);
fill: var(--el-color-primary);
animation: custom-spin-move 1s infinite linear alternate;
opacity: 0.3;
animation-delay: 0.4s;
}
.loading-path .dot3 {
transform: translate(3.75px, calc(100% - 3.75px));
fill: var(--el-color-primary);
animation: custom-spin-move 1s infinite linear alternate;
opacity: 0.3;
animation-delay: 1.2s;
}
.loading-path .dot4 {
transform: translate(calc(100% - 3.75px), calc(100% - 3.75px));
fill: var(--el-color-primary);
animation: custom-spin-move 1s infinite linear alternate;
opacity: 0.3;
animation-delay: 0.8s;
}
@keyframes loading-rotate {
to {
transform: rotate(360deg);
}
}
@keyframes loading-dash {
0% {
stroke-dasharray: 1, 200;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray: 90, 150;
stroke-dashoffset: -40px;
}
100% {
stroke-dasharray: 90, 150;
stroke-dashoffset: -120px;
}
}
@keyframes custom-spin-move {
to {
opacity: 1;
}
}
빈 값 (Empty Values) 2.7.0
빈 문자열을 지원하고 싶다면 empty-values를 [null, undefined]로 설정해요. 지운 값을 null로 바꾸고 싶다면 value-on-clear를 null로 설정해요.
커스텀 라벨 (Custom Label) 2.7.4
라벨을 커스터마이징할 수 있어요.
import { ref } from 'vue'
const value1 = ref('Option1')
const value2 = ref(['Option1'])
const options = [
{
value: 'Option1',
label: 'Label1',
},
{
value: 'Option2',
label: 'Label2',
},
{
value: 'Option3',
label: 'Label3',
},
{
value: 'Option4',
label: 'Label4',
},
{
value: 'Option5',
label: 'Label5',
},
]
Select API
Select Attributes
| Name | Description | Type | Default |
|---|---|---|---|
| model-value / v-model | 바인딩 값 | string / number / boolean / object / array | — |
| multiple | 다중 선택 활성화 여부 | boolean | false |
| options 2.10.5 | 옵션의 데이터, value와 label, disabled의 키는 props로 커스터마이징할 수 있어요 | array | — |
| props 2.10.5 | 설정 옵션 | object | — |
| disabled | Select 비활성화 여부 | boolean | false |
| value-key | value의 고유 식별 키 이름, value가 객체일 때 필수 | string | value |
| size | Input의 크기 | enum | — |
| clearable | select를 지울 수 있는지 여부 | boolean | false |
| collapse-tags | 다중 선택 시 태그를 텍스트로 접을지 여부 | boolean | false |
| collapse-tags-tooltip 2.3.0 | collapse-tags 텍스트 위에 마우스를 올렸을 때 모든 선택 태그를 표시할지 여부. 사용하려면 collapse-tags가 true여야 해요 | boolean | false |
| tag-tooltip 2.13.3 | collapse-tags tooltip의 설정 객체. 사용하려면 collapse-tags와 collapse-tags-tooltip이 true여야 해요 | object | {} |
| multiple-limit | multiple이 true일 때 사용자가 선택할 수 있는 최대 옵션 수. 0이면 제한 없음 | number | 0 |
| id | 네이티브 input id | string | — |
| name | select input의 name 속성 | string | — |
| effect | tooltip 테마, 내장 테마: dark / light | enum / string | light |
| autocomplete | select input의 autocomplete 속성 | string | off |
| placeholder | placeholder, 기본은 'Select' | string | — |
| filterable | Select 필터링 가능 여부 | boolean | false |
| allow-create | 새 항목 생성 허용 여부. 사용하려면 filterable이 true여야 해요 | boolean | false |
| filter-method | 커스텀 필터 메서드, 첫 번째 매개변수는 현재 입력 값. 사용하려면 filterable이 true여야 해요 | Function | — |
| remote | 서버에서 옵션을 로드하는지 여부 | boolean | false |
| debounce 2.11.7 | 원격 검색 중 디바운스 지연(밀리초) | number | 300 |
| remote-method | 입력 값이 변경될 때 호출되는 함수. 매개변수는 현재 입력 값. 사용하려면 filterable이 true여야 해요 | Function | — |
| remote-show-suffix | 원격 검색 방식에서 접미 아이콘 표시 | boolean | false |
| loading | Select가 서버에서 데이터를 로드하는지 여부 | boolean | false |
| loading-text | 서버에서 데이터를 로드하는 동안 표시되는 텍스트, 기본은 'Loading' | string | — |
| no-match-text | 필터링 쿼리와 일치하는 데이터가 없을 때 표시되는 텍스트, empty 슬롯도 사용 가능, 기본은 'No matching data' | string | — |
| no-data-text | 옵션이 없을 때 표시되는 텍스트, empty 슬롯도 사용 가능, 기본은 'No data' | string | — |
| popper-class | Select 드롭다운과 태그 tooltip의 커스텀 클래스 이름 | string | '' |
| popper-style 2.11.0 | Select 드롭다운과 태그 tooltip의 커스텀 스타일 | string / object | — |
| reserve-keyword | multiple과 filterable이 true일 때 옵션 선택 후 현재 키워드를 유지할지 여부 | boolean | true |
| default-first-option | Enter 키로 첫 번째 일치 옵션 선택. filterable 또는 remote와 함께 사용 | boolean | false |
| teleported | select 드롭다운 텔레포트 여부, true면 append-to가 설정한 곳으로 텔레포트돼요 | boolean | true |
| append-to 2.8.4 | select 드롭다운이 붙는 요소 | CSSSelector / HTMLElement | — |
| persistent | select 드롭다운이 비활성이고 persistent가 false일 때 드롭다운이 파괴됨 | boolean | true |
| automatic-dropdown | 필터링 불가 Select에서 입력 포커스 시 옵션 메뉴가 팝업될지 여부 | boolean | false |
| clear-icon | 커스텀 지우기 아이콘 컴포넌트 | string / object | CircleClose |
| fit-input-width | 드롭다운 너비가 입력과 같은지 여부 | boolean | false |
| suffix-icon | 커스텀 접미 아이콘 컴포넌트 | string / object | ArrowDown |
| tag-type | 태그 타입 | enum | info |
| tag-effect 2.7.7 | 태그 효과 | enum | light |
| validate-event | 폼 검증 트리거 여부 | boolean | true |
| offset 2.8.8 | 드롭다운의 오프셋 | number | 12 |
| show-arrow 2.8.8 | 드롭다운에 화살표가 있는지 여부 | boolean | true |
| placement 2.2.17 | 드롭다운 위치 | enum | bottom-start |
| fallback-placements 2.5.6 | 드롭다운 popper.js의 가능한 위치 목록 | array | ['bottom-start', 'top-start', 'right', 'left'] |
| max-collapse-tags 2.3.0 | 표시할 최대 태그 수. 사용하려면 collapse-tags가 true여야 해요 | number | 1 |
| popper-options | popper.js 매개변수 | object (popper.js 문서 참고) | {} |
| aria-label a11y | 네이티브 input의 aria-label과 동일 | string | — |
| empty-values 2.7.0 | 컴포넌트의 빈 값, config-provider 참고 | array | — |
| value-on-clear 2.7.0 | 지우기 반환 값, config-provider 참고 | string / number / boolean / Function | — |
| suffix-transition deprecated | 드롭다운 아이콘이 나타나고/사라질 때의 애니메이션 | boolean | true |
| tabindex 2.9.0 | input의 tabindex | string / number | — |
WARNING
suffix-transition은 deprecated되었고 2.4.0에서 제거될 예정이에요. override 스타일 방식을 사용하세요.
props
| Attribute | Description | Type | Default |
|---|---|---|---|
| value | 노드 객체의 어떤 키를 노드의 value로 사용할지 지정 | string | value |
| label | 노드 객체의 어떤 키를 노드의 label로 사용할지 지정 | string | label |
| options 2.11.0 | 노드 객체의 어떤 키를 노드의 children으로 사용할지 지정 | string | options |
| disabled | 노드 객체의 어떤 키를 노드의 disabled로 사용할지 지정 | string | disabled |
tag-tooltip 2.13.3
대체 메커니즘 (Fallback Mechanism)
tag-tooltip의 속성은 다음 우선순위를 따르는 데요:
tag-tooltip객체 내부에 명시적으로 정의된 필드.el-select에서 상속된 공유 props (예:effect,popper-class,popper-style,teleported,append-to,popper-options).- 기본
el-tooltip컴포넌트의 기본값. 이렇게 하면 Select 드롭다운과 기본적으로 일관성을 유지하면서 태그의 특정 tooltip 동작을 재정의할 수 있어요.
사용자 지정 컨테이너 배치 (Custom Container Positioning)
Tooltip을 커스텀 컨테이너에 추가할 때(append-to 속성) 정확한 배치를 위해 컨테이너에 position: relative 또는 position: absolute를 설정해야 해요. 또한 Tooltip이 경계를 넘는 것을 막아야 한다면 컨테이너에 overflow: hidden을 적용할 수 있어요.
| Attribute | Description | Type | Default |
|---|---|---|---|
| append-to | tooltip CONTENT가 붙는 요소 | CSSSelector / HTMLElement | — |
| placement | Tooltip의 위치 | enum | bottom |
| fallback-placements | Tooltip popper.js의 가능한 위치 목록 | array | ['bottom', 'top', 'right', 'left'] |
| effect | Tooltip 테마, 내장 테마: dark / light | enum / string | — |
| popper-class | Tooltip popper의 커스텀 클래스 이름 | string | — |
| popper-style | Tooltip popper의 커스텀 스타일 | string / object | — |
| transition | 애니메이션 이름 | string | — |
| teleported | tooltip 내용 텔레포트 여부, true면 append-to가 설정한 곳으로 텔레포트돼요 | boolean | — |
| popper-options | popper.js 매개변수 | object (popper.js 문서 참고) | — |
| show-after | 나타나는 지연 시간(밀리초) | number | — |
| hide-after | 사라지는 지연 시간(밀리초) | number | — |
| auto-close | tooltip을 숨기기까지의 타임아웃(밀리초) | number | — |
| offset | Tooltip의 오프셋 | number | — |
Select Events
| Name | Description | Type |
|---|---|---|
| change | 선택된 값이 변경될 때 트리거 | Function |
| visible-change | 드롭다운이 나타나거나 사라질 때 트리거 | Function |
| remove-tag | 다중 모드에서 태그가 제거될 때 트리거 | Function |
| clear | clearable Select에서 지우기 아이콘이 클릭될 때 트리거 | Function |
| blur | Input이 블러될 때 트리거 | Function |
| focus | Input이 포커스될 때 트리거 | Function |
| popup-scroll 2.9.4 | 드롭다운이 스크롤될 때 트리거 | Function |
| end-reached 2.14.0 | 드롭다운 스크롤이 끝에 도달할 때 트리거 | Function |
Select Slots
| Name | Description | Subtags |
|---|---|---|
| default | 옵션 컴포넌트 목록 | Option Group / Option |
| header 2.4.3 | 드롭다운 상단의 내용 | — |
| footer 2.4.3 | 드롭다운 하단의 내용 | — |
| prefix | Select 접두사로서의 내용 | — |
| empty | 옵션이 없을 때의 내용 | — |
| tag 2.5.0 | Select 태그로서의 내용, subTags 데이터, selectDisabled, deleteTag는 2.10.3에서 도입 | object |
| loading 2.5.2 | Select 로딩으로서의 내용 | — |
| label 2.7.4 | Select 라벨로서의 내용, index는 2.11.2에서 도입 | object |
Select Exposes
| Name | Description | Type |
|---|---|---|
| focus | Input 컴포넌트 포커스 | Function |
| blur | Input 컴포넌트 블러, 드롭다운 숨김 | Function |
| selectedLabel 2.8.5 | 현재 선택된 라벨 가져오기 | object |
Option Group API
Option Group Attributes
| Name | Description | Type | Default |
|---|---|---|---|
| label | 그룹 이름 | string | — |
| disabled | 이 그룹의 모든 옵션 비활성화 여부 | boolean | false |
Option Group Slots
| Name | Description | Subtags |
|---|---|---|
| default | 기본 내용 커스터마이징 | Option |
Option API
Option Attributes
| Name | Description | Type | Default |
|---|---|---|---|
| value | option의 값 | string / number / boolean / object | — |
| label | option의 라벨, 생략하면 value와 같아요 | string / number | — |
| disabled | option 비활성화 여부 | boolean | false |
Option Slots
| Name | Description |
|---|---|
| default | 기본 내용 커스터마이징 |
더 알아보기 (Learn more)
- Rate 컴포넌트 — 평점
- Virtualized Select 컴포넌트 — 가상화 셀렉트
- Element Plus 시작하기 — 프로젝트 설정