AutoComplete 자동 완성
사용자가 입력하려는 내용을 미리 제안해 주는 자동 완성 컴포넌트예요.
출처: 문서
본문
언제 사용하나요
사용자가 입력한 일부 문자를 바탕으로, 앞으로 입력할 내용이 무엇일지 추론해야 할 때 사용해요.
기본 사용법
source로 자동 완성에 쓸 데이터 소스를 설정해요.
:::demo
<template>
<d-auto-complete
:delay="1000"
:source="source"
v-model="value"
:allow-empty-value-search="allowEmptyValueSearch"
:select-value="selectValue"
:trans-input-focus-emit="transInputFocusEmit"
:position="position"
:width="420"
:append-to-body="false"
>
</d-auto-complete>
</template>
<script>
import { defineComponent, ref } from 'vue';
export default defineComponent({
setup() {
const value = ref('');
const allowEmptyValueSearch = ref(true);
const source = ref([
'C#',
'C',
'C++',
'CPython',
'Java',
'JavaScript',
'Go',
'Python',
'Ruby',
'F#',
'TypeScript',
'SQL',
'LiveScript',
'CoffeeScript',
]);
const selectValue = (e) => {
console.log('selectValue', e);
};
const transInputFocusEmit = () => {
console.log('transInputFocusEmit');
};
const position = ref(['bottom']);
return {
value,
source,
allowEmptyValueSearch,
transInputFocusEmit,
selectValue,
position,
};
},
});
</script>
<style></style>
:::
크기
sm, md, lg 세 가지 크기를 지원하며, 기본값은 md예요.
:::demo
<template>
<h4>Small</h4>
<d-auto-complete size="sm" :source="source" v-model="value1" :width="420"> </d-auto-complete>
<h4>Middle</h4>
<d-auto-complete :source="source" v-model="value2" :width="420"> </d-auto-complete>
<h4>Large</h4>
<d-auto-complete size="lg" :source="source" v-model="value3" :width="420"> </d-auto-complete>
</template>
<script>
import { defineComponent, ref } from 'vue';
export default defineComponent({
setup() {
const value1 = ref('');
const value2 = ref('');
const value3 = ref('');
const source = ref(['C#', 'C', 'C++']);
return {
value1,
value2,
value3,
source,
};
},
});
</script>
<style></style>
:::
비활성화 설정
disabled로 비활성화 여부를 설정해요.
:::demo
<template>
<d-row type="flex">
<d-col :flex="4">
<d-auto-complete :source="source" v-model="value" :disabled="isDisabled"> </d-auto-complete>
</d-col>
<d-col :flex="2">
<d-button id="primaryBtn" @click="toggle" style="margin-left:10px">
{{ isDisabled ? '点击启用' : '点击禁用' }}
</d-button>
</d-col>
</d-row>
</template>
<script>
import { defineComponent, ref } from 'vue';
export default defineComponent({
setup() {
const value = ref('');
const source = ref([
'C#',
'C',
'C++',
'CPython',
'Java',
'JavaScript',
'Go',
'Python',
'Ruby',
'F#',
'TypeScript',
'SQL',
'LiveScript',
'CoffeeScript',
]);
const isDisabled = ref(false);
function toggle() {
isDisabled.value = !isDisabled.value;
}
return {
value,
source,
isDisabled,
toggle,
};
},
});
</script>
<style></style>
:::
데이터 매칭 방법 커스터마이즈
search-fn으로 데이터를 찾는 방법과 반환되는 데이터 형식을 직접 정의할 수 있어요.
:::demo
<template>
<d-auto-complete v-model="value" :search-fn="searchFn" disabled-key="disabled" is-searching :delay="1000" :formatter="formatter">
<template #searching="slotProps">
<div>
{{ `searching: ${slotProps}` }}
</div>
</template>
</d-auto-complete>
</template>
<script>
import { defineComponent, ref } from 'vue';
export default defineComponent({
setup() {
const value = ref('');
const mySource = ref([
{
label: 'C#',
disabled: false,
},
{
label: 'C++',
disabled: false,
},
{
label: 'CPython',
disabled: false,
},
{
label: 'Java',
disabled: false,
},
{
label: 'JavaScript',
disabled: false,
},
{
label: 'Go',
disabled: false,
},
{
label: 'Ruby',
disabled: false,
},
{
label: 'F#',
disabled: false,
},
{
label: 'TypeScript',
disabled: false,
},
{
label: 'SQL',
disabled: true,
},
{
label: 'LiveScript',
disabled: false,
},
{
label: 'CoffeeScript',
disabled: false,
},
]);
const formatter = (item) => {
return item.label;
};
//trem:input输入内容
const searchFn = async (trem) => {
let arr = [];
await new Promise((resolve) => {
setTimeout(() => {
resolve();
}, 1000);
});
mySource.value.forEach((item) => {
let cur = item.label;
cur = cur.toLowerCase();
if (cur.startsWith(trem)) {
arr.push(item);
}
});
return arr;
};
return {
value,
searchFn,
formatter,
};
},
});
</script>
<style></style>
:::
템플릿 커스터마이즈
item, nothing 슬롯으로 드롭다운 항목과 매칭 결과가 없을 때의 안내 화면을 직접 정의할 수 있어요.
:::demo
<template>
<d-auto-complete :source="source" v-model="value">
<template #item="slotProps">
<div>第{{ slotProps.index }}项: {{ slotProps.item }}</div>
</template>
<template #nothing="slotProps">
<div>
{{ `没有匹配项: ${slotProps}` }}
</div>
</template>
</d-auto-complete>
</template>
<script>
import { defineComponent, ref } from 'vue';
export default defineComponent({
setup() {
const value = ref('');
const source = ref([
'C#',
'C',
'C++',
'CPython',
'Java',
'JavaScript',
'Go',
'Python',
'Ruby',
'F#',
'TypeScript',
'SQL',
'LiveScript',
'CoffeeScript',
]);
return {
value,
source,
};
},
});
</script>
<style></style>
:::
최근 입력
latest-source로 최근 입력 항목을 설정해요.
:::demo
<template>
<d-auto-complete :source="source" v-model="value" :latest-source="latestSource"> </d-auto-complete>
</template>
<script>
import { defineComponent, ref, toRefs, getCurrentInstance } from 'vue';
export default defineComponent({
setup() {
const value = ref('');
const latestSource = ref(['JavaScript', 'TypeScript']);
const source = ref([
'C#',
'C',
'C++',
'CPython',
'Java',
'JavaScript',
'Go',
'Python',
'Ruby',
'F#',
'TypeScript',
'SQL',
'LiveScript',
'CoffeeScript',
]);
return {
value,
source,
latestSource,
};
},
});
</script>
<style></style>
:::
지연 로딩 사용하기
enable-lazy-load로 지연 로딩을 켤 수 있어요.
:::demo
<template>
<d-auto-complete
ref="autoCompleteRef"
:source="source"
v-model="value"
enable-lazy-load
:load-more="loadMore"
scene-type="select"
:value-parser="valueParser"
>
</d-auto-complete>
</template>
<script>
import { defineComponent, ref, toRefs, getCurrentInstance } from 'vue';
export default defineComponent({
setup() {
const value = ref('');
const source = ref([
'C#',
'C',
'C++',
'CPython',
'Java',
'JavaScript',
'Go',
'Python',
'Ruby',
'F#',
'TypeScript',
'SQL',
'LiveScript',
'CoffeeScript',
'C1',
'C2',
'C3',
'C4',
'C5',
'C6',
'C7',
]);
const autoCompleteRef = ref(null);
const loadMore = () => {
setTimeout(() => {
source.value.push('lazyData' + source.value.length);
autoCompleteRef.value?.loadFinish();
}, 3000);
};
const valueParser = (e) => {
return e + '123';
};
return {
value,
source,
loadMore,
valueParser,
autoCompleteRef,
};
},
});
</script>
<style></style>
:::
AutoComplete 파라미터
| 파라미터 | 타입 | 기본값 | 설명 | Demo 링크 |
|---|---|---|---|---|
| size | AutoCompleteSize |
'md' | 선택, 입력창 크기. 'lg', 'md', 'sm' 세 가지 |
크기 |
| placeholder | string |
'Search' | 선택, 플레이스홀더 | -- |
| source | SourceType |
-- | 필수, searchFn이 있으면 생략 가능 | 기본 사용법 |
| allow-empty-value-search | boolean |
false | 선택, 바인딩된 입력창 value가 비었을 때 검색 힌트 동작 수행 여부 | 기본 사용법 |
| append-to-body | boolean |
false | 선택, 드롭다운을 body에 append 할지 여부 | 기본 사용법 |
| position | Placement |
['bottom'] |
선택, 드롭다운과 입력창의 상대 위치 지정 | 기본 사용법 |
| disabled | boolean |
false | 선택, 디렉티브 비활성화 여부 | 비활성화 설정 |
| delay | number |
300 | 선택, delay 시간이 지나고 새 값 입력이 없을 때만 검색 쿼리 실행(ms) |
기본 사용법 |
| disabled-key | string |
-- | 선택, 개별 옵션 비활성화 | 커스텀 데이터 매칭 메서드 |
| formatter | (item: any) => string |
defaultFormatter |
선택, 포맷팅 함수 | 커스텀 데이터 매칭 메서드 |
| is-searching | boolean |
false | 선택, 검색 중 여부. searchingTemplate 표시 제어용 | 커스텀 데이터 매칭 메서드 |
| scene-type | string |
-- | 선택, 값은 'select' 또는 'suggest' | 지연 로딩 활성화 |
| search-fn | (term: string) => Array<any> |
defaultSearchFn |
선택, 검색 필터 커스텀 | 커스텀 데이터 매칭 메서드 |
| tips-text | string |
'최근 입력' | 선택, 힌트 텍스트 | 비활성화 설정 |
| latest-source | Array<any> |
-- | 선택, 최근 입력 | 최근 입력 |
| value-parser | (item: any) => any |
defaultValueParse |
선택, 선택 후 데이터 처리 | 지연 로딩 활성화 |
| enable-lazy-load | boolean |
false | 선택, 지연 로딩 허용 여부 | 지연 로딩 활성화 |
| width | number |
400 | 선택, 너비 조정(px) |
기본 사용법 |
| show-animation | boolean |
true | 선택, 애니메이션 사용 여부 | |
| prefix | string |
-- | 선택, 접두사 아이콘 커스텀 | 아이콘 입력란 |
| suffix | string |
-- | 선택, 접미사 아이콘 커스텀 | 아이콘 입력란 |
| clearable | boolean |
false | 선택, 비우기 가능 여부 | d-input 한 번에 비우기 참고 |
| show-glow-style | boolean |
true | 선택, 호버 발광 효과 표시 여부 |
AutoComplete 이벤트
| 파라미터 | 타입 | 설명 | Demo 링크 |
|---|---|---|---|
| load-more | function |
지연 로딩 트리거 이벤트. enable-lazy-load와 함께 사용하며, $event.loadFinish()로 loading 상태를 닫습니다. $event는 AutoCompleteComponent 인스턴스 |
지연 로딩 활성화 |
| select-value | function(value) |
선택, 옵션 선택 후 콜백 함수 | 기본 사용법 |
| trans-input-focus-emit | function |
선택, Input focus 시 콜백 함수 | 기본 사용법 |
AutoComplete 슬롯
| 슬롯명 | 설명 | Demo 링크 |
|---|---|---|
| item | 선택, 표시 템플릿 커스텀. slotProps: { index: 인덱스, item: 현재 항목 내용 } | 커스텀 템플릿 표시 |
| nothing | 선택, 매칭 항목이 없을 때의 표시 결과. slotProps: 입력 내용 | 커스텀 템플릿 표시 |
| searching | 선택, 검색 중 표시 템플릿 커스텀. slotProps: 입력 내용 | 커스텀 데이터 매칭 메서드 |
| prefix | 선택, 입력창 헤더 콘텐츠 | 아이콘 입력란 |
| suffix | 선택, 입력창 푸터 콘텐츠 | 아이콘 입력란 |
| prepend | 선택, 입력창 앞쪽 콘텐츠 | 복합형 입력란 |
| append | 선택, 입력창 뒤쪽 콘텐츠 | 복합형 입력란 |
타입 정의
SourceType
interface SourceItemObj {
label: string;
disabled: boolean;
[propName: string]: unknown;
}
type SourceType = Array<string> | Array<SourceItemObj>;
Placement
type Placement =
| 'top'
| 'right'
| 'bottom'
| 'left'
| 'top-start'
| 'top-end'
| 'right-start'
| 'right-end'
| 'bottom-start'
| 'bottom-end'
| 'left-start'
| 'left-end';
defaultSearchFn
defaultSearchFn = (term: string) => {
type ItemType = typeof source.value[0];
const arr: ItemType[] = [];
source.value.forEach((item) => {
let cur = formatter.value(item as ItemType);
cur = cur.toLowerCase();
if (cur.startsWith(term)) {
arr.push(item);
}
});
return arr as SourceType;
};
term은 입력한 검색 키워드예요.
defaultFormatter
defaultFormatter = (item: string | SourceItemObj) => {
if (typeof item === 'string') {
return item;
}
return item !== null ? item.label || item.toString() : '';
};
item은 데이터 항목이에요.
defaultValueParse
defaultValueParse = (item) => item;
AutoCompleteSize
type AutoCompleteSize = 'sm' | 'md' | 'lg';
더 알아보기 (Learn more)
search-fn과 슬롯을 활용하면 검색 동작과 표시 형태를 자유롭게 바꿀 수 있어요. 자세한 내용은 DevUI 공식 문서를 참고해 보세요.