본문으로 바로가기 본문 바로가기
WIKI 기술 지식 베이스

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 공식 문서를 참고해 보세요.