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

드롭다운의 헤더를 커스터마이징할 수 있어요. 슬롯으로 내용을 커스터마이징해요.

드롭다운의 푸터를 커스터마이징할 수 있어요. 슬롯으로 내용을 커스터마이징해요.

그룹화 (Grouping)

옵션을 그룹으로 표시해요. el-option-group을 사용해서 옵션을 그룹화하고, 그 label 속성이 그룹의 이름을 나타내요.

옵션 필터링 (Option filtering)

원하는 옵션을 필터링할 수 있어요. el-select에 filterable을 추가하면 필터링이 활성화돼요. 기본적으로 Select는 label 속성이 입력 값을 포함하는 모든 옵션을 찾아요. 다른 필터링 전략을 선호하면 filter-method를 전달할 수 있어요. filter-method는 입력 값이 변경될 때 호출되는 Function이고, 매개변수는 현재 입력 값이에요.

키워드를 입력하고 서버에서 데이터를 검색해요. 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)