Skip to content

Компонент DaData-подсказок для Vue 3.

Попробуйте демо, чтобы ознакомиться с возможностями компонента:

Демо

Установка

bash
npm i @dadata-sdk/vue

Или

bash
pnpm i @dadata-sdk/vue

Или напрямую из последнего коммита на GitHub:

bash
pnpm add @dadata-sdk/vue@github:alexchexes/dadata-sdk#rewritten&path:/packages/vue-dadata

Использование

vue
<script setup>
import { ref } from 'vue';
import { VueDadata } from 'vue-dadata';
// use shipped CSS if needed:
import 'vue-dadata/dist/vue-dadata.css';

const token = import.meta.env.VITE_APP_DADATA_API_KEY; // API key

const query = ref(''); // input field value
const suggestion = ref(undefined); // selected suggestion
</script>

<template>
  <VueDadata v-model="query" v-model:suggestion="suggestion" :token="token" />
</template>

V-Models

v-model

  • Обязательный
  • Тип: string

v‑model для текста запроса. Значение используется при вызовах API и синхронизировано с полем ввода (<input>) всё время, кроме как при навигации по подсказкам с клавиатуры (клавишами ↑↓) — в этот момент поле ввода отображает текст из «подсвеченной» в данный момент подсказки, а значение v-model сохраняет текст, который был в поле до начала навигации. После выбора подсказки или выхода (Esc, Клик вне элемента), поле снова синхронизировано со значением в данном v-model.

v-model:suggestion

  • Тип: object | undefined

v‑model для объекта выбранной в данный момент подсказки. Обеспечивает простой доступ к объекту, но работает в обе стороны — можно задать «начальную» подсказку при загрузке страницы без необходимости вызывать API. При установке непустого объекта извне, будет также обновлён v-model текста запроса.

Пропсы

Основные настройки

token

string

Ваш API-ключ (token) DaData.

suggestType

string

Тип подсказок, то есть используемый эндпоинт suggest API DaData:

По умолчанию address

httpCache

boolean

Если false, HTTP-запросы не будут кэшироваться.
По умолчанию true

url

string

Пользовательский URL API.
Полезно, если вы проксируете запросы к DaData.

Важно: эндпоинт (то есть suggestType) в настоящий момент не добавляется автоматически.
Нужно передать полный URL вашего эндпоинта, например https://my-api-proxy.example.com/suggest/address.

Если не передано, итоговый URL собирается из базового suggest API DaData (.../api/4_1/rs/suggest/) + suggestType.

payload

OptionalSuggestPayload (object)

Пользовательский payload для API-запроса.
Поля, указанные здесь, будут добавлены в итоговый payload, переопределяя существующие значения.

headers

PlainHeaders (object)

Пользовательские HTTP-заголовки для API-запроса.
Заголовки, указанные здесь, будут добавлены в итоговые headers переопределяя существующие значения.

Запросы к Адресам

count

number

Максимальное количество подсказок, запрашиваемых у API DaData.
Макс: 20, по умолчанию: 10

locationsBoost

KladrIdFilter (object) | string | number | array

kladr_id или массив kladr_id региона/города, который нужно приоритизировать в подсказках.
Соответствует параметру API locations_boost.

Примеры:

Макс: 10 элементов

locationsFilter

LocationRestriction (object) | string | number | array

Ограничивает поиск конкретными локациями (параметр API locations).
Макс: 10 элементов

Например, при suggestType=address, чтобы искать только по городу Воронежу и Ростовской области:
:locationsFilter="[{'region':'Воронежская','city':'Воронеж'},{'region':'Ростовская'}]"

Для party и bank поддерживается только фильтр kladr_id.

fromBound

string

Ограничивает тип адресного объекта, с которого DaData начинает поиск:

  • country | region | area | city | settlement | planning_structure | street | house

Соответствует параметру API from_bound.

toBound

string

Ограничивает тип адресного объекта, до которого DaData выполняет поиск:

  • country | region | area | city | settlement | planning_structure | street | house | flat

Соответствует параметру API to_bound.

https://confluence.hflabs.ru/pages/viewpage.action?pageId=222888017

restrictValue

boolean

Используется вместе с locationsFilter. Если true, отображаемая подсказка
(то есть поле value) будет без частей адреса до уровня ограничения.

Например, если в фильтре указать region, этот регион не попадет в результат;
если указать city, из результата будут исключены и регион, и город.

Соответствует параметру API restrict_value.

radiusFilter

RadiusFilter (object)

Ограничивает поиск заданным радиусом вокруг точки с широтой и долготой.
Пример: {lat: '59.244634', lon: '39.913355', radius_meters: 200}

Соответствует параметру API locations_geo.
See https://confluence.hflabs.ru/pages/viewpage.action?pageId=990871806

division

string

Тип территориального деления:

  • ADMINISTRATIVE (административное): Московская обл, г Одинцово, село Никольское
  • MUNICIPAL (муниципальное): Московская обл, г.о. Одинцовский, село Никольское

Также влияет на набор полей внутри suggestion.data.

По умолчанию: 'ADMINISTRATIVE'
See https://confluence.hflabs.ru/pages/viewpage.action?pageId=1326056589

language

string

Язык в возвращаемых подсказках по адресам. RU или EN.

EN - почти всегда простая транслитерация латиницей,
однако для некоторых городов, например, "Moscow" - поля будут содержать реальный перевод,
причём переведён будет также тип города - "city" (тогда как для других это обычно "gorod").

По умолчанию: RU.

https://confluence.hflabs.ru/pages/viewpage.action?pageId=976388726

Запросы к другим API

entityType

string | (string | array) | (string | array) | (string | array)

Тип организации или банка (для подсказок party, party_by, party_kz и bank).

entityStatus

(string | array) | (string | array) | (string | array)

Статус организации или банка (для подсказок party, party_by и bank)

branchType

string | array

Фильтр по типу филиала (для подсказок party)

  • MAIN - искать только головные организации
  • BRANCH - искать только филиалы

See https://confluence.hflabs.ru/pages/viewpage.action?pageId=568918095

okved

string | array

Фильтр по коду ОКВЭД (для подсказок party). Макс: 10 элементов

fioParts

string | array

Фильтр по частям ФИО (для подсказок fio, см. https://dadata.ru/api/suggest/name/).

Примеры:

  • Только имена: ['NAME'] или NAME
  • Имена и отчества: ['NAME', 'PATRONYMIC']
  • Имена и фамилии: ['NAME', 'SURNAME']

fioGender

string

Фильтр по полу (для подсказок fio).

  • UNKNOWN / MALE / FEMALE

filters

SuggestFmsUnitFilter (object) | SuggestFnsUnitFilter (object) | SuggestMetroFilter (object) | SuggestMktuFilter (object) | SuggestOkpd2Filter (object) | SuggestOkved2Filter (object) | SuggestPartyByFilter (object) | SuggestPartyKzFilter (object) | SuggestPostalUnitFilter (object) | SuggestCourtFilter (object) | array

Фильтры для API, у которых нет отдельных props-опций,
например fms_unit, fns_unit, metro, mktu, okpd2, okved2, postal_unit, court.

Чтобы задать filters для party_by и party_kz, используйте entityStatus
и entityType, как и для обычного party.

Поведение компонента

debounce

number

Задержка (в мс) после изменения ввода (query) перед отправкой запроса.

Работает по принципу debounce: если ввод продолжает изменяться,
запрос не будет отправлен до тех пор, пока с последнего изменения
не прошло это количество миллисекунд.

По умолчанию 100

minChars

number

Минимальная длина ввода (query), начиная с которой подсказки начинают работать.
По умолчанию 1

disabled

boolean

Задаёт атрибут disabled у поля ввода, отключает подсказки и все взаимодействия.
По умолчанию false

placeholder

string

Текст для атрибута placeholder у поля ввода.

inputName

string

Значение атрибута name у поля ввода.
По умолчанию dadata-input

inputAttributes

suggestionsHint

string

Текст, который отображается над списком подсказок.

noSuggestionsHint

string | boolean

Текст, отображаемый на месте подсказок, когда ничего не найдено.

Если используете слот #hint, передайте true для отображения своего элемента
при отсутствии подсказок, чтобы контейнер оставался видимым.

classes

VueDadataClasses (object)

Пользовательские имена CSS-классов для элементов компонента.
Значения по умолчанию: DEFAULT_CLASSES

showOnFocus

string | boolean

Управляет тем, в каких случаях при фокусе на поле ввода должен быть показан список подсказок.

  • false: никогда не показывать список по фокусу
  • 'always': всегда показывать список по фокусу, если поле ввода не пустое и список подсказок не пуст
  • 'no_selection': показывать список по фокусу, если сейчас нет выбранной подсказки

По умолчанию: 'no_selection'

selectOnBlur

boolean

Если true, при потере полем ввода фокуса будет автоматически "выбрана" первая подсказка.
По умолчанию: false

selectOnEnter

boolean

Если true, нажатие Enter выбирает первую подсказку, если список открыт.
По умолчанию: true

enrichOnSelect

boolean

Нужно ли отправлять дополнительный запрос после выбора подсказки, чтобы дополнить ее
данными вроде geo_lat, geo_lon, city_district (а также получить полный value,
если используется restrictValue).

Поставьте false, если хотите сэкономить запросы к API и эти данные вам не нужны.
По умолчанию: true

clearOnChange

string | boolean

Определяет, удалять ли объект выбранной подсказки из v-model:suggestion
при изменении текста ввода (query).

  • false: выбранная подсказка никогда не очищается при изменении query
  • 'any': подсказка очищается при любом изменении query
  • 'significant': подсказка очищается только если новое значение query после нормализации
    (trim, case-folding) отличается от предыдущего

По умолчанию: 'significant'

addSpace

boolean

Если true, после выбора подсказки в input будет добавлен пробел. Например,
пользователь сможет выбрать улицу и сразу продолжить вводить номер дома.
По умолчанию true

continueSelecting

boolean

Если true, список подсказок останется видимым после выбора подсказки.
По умолчанию: false

showClearButton

boolean

Если true, в непустом поле ввода будет показываться кнопка очистки (×).
По умолчанию: false

focusOnMounted

boolean

Если true, input сразу получит фокус после загрузки компонента (хук onMounted).
По умолчанию false

forceShow

boolean

Принудительно держит список подсказок видимым.
Полезно во время разработки, при настройке стилей, и т.д.
По умолчанию: false

forceHide

boolean

Принудительно держит список подсказок скрытым.
По умолчанию: false

События компонента

СобытиеКогдаЧто передаётся
@errorВ случае любой ошибкиunknown
@selectПодсказка выбрана (по клику, по нажатию "Enter", или автоматически если selectOnBlur=true)(suggestion: object, selectType: string)
@enrichedДополнительные данные об адресе получены (если enrichOnSelect=true)(suggestion: object, diff: object | null)
@enrichFailНе удалось получить дополнительные данные об адресе (если enrichOnSelect=true)string (suggestion.unrestricted_value)
@focusПоле ввода получило фокусFocusEvent
@blurПоле ввода потеряло фокусFocusEvent

Слоты

В пропсы каждого слота передаётся mergedClasses - объект со всеми используемыми компонентом CSS-классами в том же формате, что и объект для пропса classes на компоненте (VueDadataClasses).

inputWrapper

Слот для замены основного видимого контейнера с полем ввода, включающего <input> и кнопку-«крестик».

В пропсы слота передаются:

  • coreInputProps - рекомендуется забиндить на свой input полностью через v-bind. Включает базовые необходимые компоненту обработчики событий @input, @keydown, @focus, @blur, а также атрибут disabled, и value, который не всегда соответствует тексту в query, поскольку может содержать текущий видимый текст при навигации по подсказкам клавиатурой.
  • browserAutoProps - атрибуты для отключения функций браузера, мешающих взаимодействию: встроенных подсказок, автозаполнения, автокоррекции и проверки правописания.
  • allInputProps - включает всё, что включено в coreInputProps и browserAutoProps, а также дополнительно, атрибуты type, class, name, и placeholder.
  • mergedClasses - используемые компонентом CSS-классы.

Пример использования:

vue
<template #inputWrapper="{ allInputProps, coreInputProps, browserAutoProps }">
  <!-- Your custom input/wrapper/anything -->
  <MyFancyInput
    v-bind="{ ...coreInputProps, ...browserAutoProps }"
    :placeholder="allInputProps.placeholder"
  />
</template>

При желании, <input> можно заменить на <textarea>, забиндив на неё все пропсы аналогичным образом.

input

Заменяет только <input>, не трогая вышестоящий контейнер и оверлей с кнопкой-«крестиком». Пропсы слота те же, что для inputwrapper. Пример:

vue
<template #input="{ allInputProps, coreInputProps, browserAutoProps }">
  <textarea v-bind="allInputProps" />
</template>

inputOverlay

Пустой слот, позволяющий добавить свои элементы внутри контейнера с inputом, например, индикатор загрузки, кнопки и подобное. Пропсов кроме mergedClasses нет. Пример:

vue
<template #inputOverlay>
  <!-- Custom loading spinner, icons, buttons, etc -->
</template>

clearButtonIcon

Заменяет иконку встроенной кнопки-«крестика» (×), не трогая сам элемент <button>. Пропсов кроме mergedClasses нет. Пример:

vue
<template #clearButtonIcon>
  <svg><!-- Custom "clear" icon --></svg>
</template>

hint

Слот позволяет добавить собственные элементы, отображаемые над списком подсказок при их наличии, либо вместо списка при их отсутствии. Например, здесь можно добавить ссылку или кнопку, когда подсказок не найдено, или свой дизайн сообщения "Выберите вариант или продолжите ввод...".

На контейнер добавлен @mousedown.prevent, чтобы исключить потерю фокуса и скрытие списка подсказок при кликах внутри контейнера.

Чтобы контейнер оставался видимым, когда подсказки не найдены, необходимо передать true в пропс компонента noSuggestionsHint.

Пропсы слота:

  • suggestionsList - текущий список подсказок
  • suggestionsHint - текст сообщения при наличии подсказок (дефолтное или из пропса suggestionsHint компонента)
  • noSuggestionsHint - текст сообщения при отсутствии подсказок (из пропса noSuggestionsHint компонента)
  • mergedClasses - используемые компонентом CSS-классы.

Пример:

vue
<!-- <VueDadata :noSuggestionsHint="true" ...> -->

<template #hint="{ suggestionsList, suggestionsHint, noSuggestionsHint }">
  <!-- Стандартное сообщение если подсказки найдены -->
  <template v-if="suggestionsList.length"> {{ suggestionsHint }} </template>

  <!-- Свой блок если подсказок нет -->
  <template v-else>
    Ничего нет...
    <button @click="reset">Сбросить фильтры?</button>
  </template>
</template>

suggestions

Заменяет полностью список подсказок (не трогая сам контейнер выпадающего списка и hint).

Пропсы слота:

  • suggestionsList - Массив из объектов подсказок
  • navigatedIndex - Индекс "подсвеченной" подсказки (при навигации клавиатурой)
  • handleSuggestionClick - Обработчик клика, который необходимо добавить на каждый элемент подсказки, чтобы функции компонента продолжали работать в полном объёме (используйте @mousedown.prevent="...")
  • mergedClasses - используемые компонентом CSS-классы.

Пример:

vue
<template #suggestions="{ suggestionsList, navigatedIndex, handleSuggestionClick }">
  <div
    v-for="(suggestion, index) in suggestionsList"
    :key="index"
    @mousedown.prevent="handleSuggestionClick(index)"
  >
    {{ suggestion.value }}
  </div>
</template>

suggestionItem

Заменяет каждый отдельный элемент списка подсказок (включая его контейнер).

Пропсы слота:

  • suggestion - объект подсказки
  • index - индекс элемента в списке (с 0)
  • isNavigated - является ли данный элемент "подсвеченным" (при навигации клавиатурой)
  • handleSuggestionClick - Обработчик клика, который необходимо добавить на ваш элемент подсказки, чтобы функции компонента продолжали работать в полном объёме (используйте @mousedown.prevent="...")
  • mergedClasses - используемые компонентом CSS-классы.

Пример:

vue
<template #suggestionItem="{ suggestion, index, isNavigated, handleSuggestionClick }">
  <button @mousedown.prevent="handleSuggestionClick(index)">
    {{ suggestion.value }}
  </button>
</template>

suggestionItemContent

Заменяет внутренний контент каждого элемента в списке подсказок, не трогая его родительский контейнер. Пропсы те же, что для suggestionItem, но без handleSuggestionClick.

vue
<template #suggestionItemContent="{ suggestion, index, isNavigated }">
  {{ suggestion.value }}
</template>

suggestionItemTitle

Заменяет элемент с основным отображаемым текстом подсказки (suggestion.value). При использовании слота понадобится добавить собственную подсветку совпадений; чтобы получить размеченные части для подсветки можно использовать экспортируемую библиотекой функцию highlightChunks.

Пропсы слота те же, что для suggestionItem, но без handleSuggestionClick.

vue
<template #suggestionItemTitle="{ suggestion, index, isNavigated }">
  <!-- Show `unrestricted_value` instead of `value` (with custom `highlight`) -->
  <span v-html="highlight(query, suggestion.unrestricted_value)" />
</template>

suggestionItemSubtitle

Заменяет элемент для размещения дополнительного текста под основным текстом подсказки. Дефолтный контент слота отображается только в определённых случаях, например для подсказок по организациям или банкам, слот же позволяет выводить дополнительное инфо в любой момент.

Пропсы те же, что для suggestionItem, но без handleSuggestionClick.

vue
<template #suggestionItemSubtitle="{ suggestion, index, isNavigated }">
  <div :class="mergedClasses.suggestionSubtitle">
    Фед. округ: {{ (suggestion.data as AddressAdminData).federal_district }}
  </div>
</template>

Методы и свойства компонента

Следующие методы и свойства доступны через template-ref компонента (<VueDadata ref='vueDadata' ... />):

NameTypeDescription
inputRefShallowRef<HTMLInputElement | null>templateRef элемента <input>
suggestionsListRef<DadataSuggestion[], DadataSuggestion[]>Текущий список подсказок или пустой массив
isDropdownVisibleComputedRef<boolean>true когда список подсказок показан
isFocusedComputedRef<boolean>true когда <input> имеет фокус
update()(options) => DadataSuggestion[]Отправить запрос и обновить список подсказок. В аргументе можно передать опции, которые перезапишут опции, переданные, установленные через пропсы. Возвращает полученный список подсказок, или выбрасывает исключение в случае ошибки.
clear()() => voidОчистить текст запроса (modelValue), v-model:suggestion и suggestionsList
show()() => voidПоказать подсказки (если они в этот момент загружены)
hide()() => voidСкрыть подсказки
focus()() => voidПередать фокус <input>
blur()() => voidУбрать фокус с <input>

Пример использования методов

vue
<script setup>
// ...
const query = ref('');
const suggestion = ref(undefined);
const vueDadata = useTemplateRef('vueDadata');

onMounted(async () => {
  // `focus()`: Autofocus the input with a small delay after page load
  setTimeout(() => {
    vueDadata.value?.focus();
  }, 300);

  // set "selected suggestion" v-model manually
  suggestion.value = {
    /*...existing suggestion object...*/
  };
  // wait one tick so that v-model:suggestion propagates and changes the `query`
  await nextTick();
  // now fetch suggestions list with `update()`
  const suggestions = await vueDadata.value?.update();
  // the updated suggestions list is also available in the return value
  console.log('Updated. Suggestions: ', suggestions);

  // and finally use `show()` to open the dropdown programmatically
  vueDadata.value?.show();
});
</script>

<template>
  <VueDadata ref="vueDadata" v-model="query" v-model:suggestion="suggestion" ... />

  <!-- Access to the fetched suggestions list -->
  <pre>{{ vueDadata?.suggestionsList }}</pre>
</template>

Внешние зависимости

Используется под капотом

Ожидается у клиента (peer-deps)