Skip to content

DaData-suggestions component for Vue 3

Try the demo playground to understand how it works.

Demo

Install

bash
npm install @dadata-sdk/vue
bash
pnpm add @dadata-sdk/vue

Or install from the latest commit on GitHub:

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

Usage

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

  • Required
  • Type: string

The v-model for the query text. The value is used in API calls and is synced with the input field (<input>) all the time, except when navigating suggestions with keyboard (↑↓ keys) — during such a navigation, the input field displays the text from the currently navigated (highlighted) suggestion, while the v-model value retains the text that was in the field before navigation began. After a suggestion is selected or navigation ends (Esc, click outside), the field will be in sync with the v-model value again.

v-model:suggestion

  • Type: object | undefined

The v-model for the currently selected suggestion object. Provides easy access to the object and works both ways — you can set an "initial" suggestion on page-load without an extra API call. When a non-empty object is set from outside, the v-model for the query text will also be updated.

Props

General options

token

string

Your DaData API key (token).

suggestType

string

Type of suggestions (Dadata suggest API endpoint):

Default address

httpCache

boolean

If false, HTTP requests will not be cached.
Default true

url

string

Custom API URL.
Useful when proxying requests to the DaData API.

Note: currently the endpoint (i.e. suggestType) is not appended automatically.
You must provide the full URL, e.g. https://my-api-proxy.example.com/suggest/address.

Default: The final URL is built from the base DaData suggest API (.../api/4_1/rs/suggest/) + suggestType.

payload

OptionalSuggestPayload (object)

Custom payload for the API request.
Any fields specified here will be added to the final request payload, or override existing values if already set.

headers

PlainHeaders (object)

Custom headers for the API request.
Any headers specified here will be added to the final request headers, or override existing values if already set.

Request options (address)

count

number

Maximum number of suggestion items to fetch from the DaData API.
Max: 20, Default: 10

locationsBoost

KladrIdFilter (object) | string | number | array

kladr_id or an array of kladr_ids for the region/city to be prioritized in suggestions.
Corresponds to the locations_boost API parameter.

Examples:

Max: 10 items

locationsFilter

LocationRestriction (object) | string | number | array

Restricts the search to specific locations (API locations parameter).
Max: 10 items

For example (when suggestType=address), to search only in Voronezh city and in Rostov region:
:locationsFilter="[{'region':'Воронежская','city':'Воронеж'},{'region':'Ростовская'}]"

For party and bank, the only supported filter is kladr_id.

fromBound

string

Limits the type of address object from which DaData begins searching:

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

Corresponds to the from_bound API parameter.

toBound

string

Limits the type of address object to which DaData performs the search:

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

Corresponds to the to_bound API parameter.

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

restrictValue

boolean

Used with locationsFilter. If true, the displayed suggestion (i.e., value field)
will exclude address parts up to the restricted level.

For example, if the filter specifies a region, that region will be omitted in the result;
if it specifies a city, both the region and city will be omitted.

Corresponds to the restrict_value API parameter.

radiusFilter

RadiusFilter (object)

Restrict the search to a specific radius around a latitude/longitude point.
Example: {lat: '59.244634', lon: '39.913355', radius_meters: 200}

Corresponds to the locations_geo API parameter.
See https://confluence.hflabs.ru/pages/viewpage.action?pageId=990871806

division

string

Type of territorial division: ADMINISTRATIVE or MUNICIPAL:

  • ADMINISTRATIVE: Московская обл, г Одинцово, село Никольское
  • MUNICIPAL: Московская обл, г.о. Одинцовский, село Никольское

Also affects set of fields inside suggestion.data
@default 'ADMINISTRATIVE'
See https://confluence.hflabs.ru/pages/viewpage.action?pageId=1326056589

language

string

Display language for address suggestions. RU or EN.

EN is almost always simple transliteration to latin script,
however, for some cities, like "Moscow", fields will be translated to English,
including the city type ("city", while for others it's often "gorod").

Default: RU.

@default 'RU'.

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

Request options (other)

entityType

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

Organization or bank type (for party, party_by, party_kz, and bank suggestions).

for party: LEGAL or INDIVIDUAL, https://confluence.hflabs.ru/pages/viewpage.action?pageId=206176337

entityStatus

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

Organization or bank status (for party, party_by and bank suggestions)

branchType

string | array

Branch type filter (for party suggestions)

  • MAIN - to search only for head offices
  • BRANCH - search only for branches

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

okved

string | array

OKVED code filter (for party suggestions). Max: 10 items

fioParts

string | array

Filter by FIO parts (for fio suggestions, see https://dadata.ru/api/suggest/name/).

Examples:

  • Names only: ['NAME'] or NAME
  • Names and patronymics: ['NAME', 'PATRONYMIC']
  • Names and surnames: ['NAME', 'SURNAME']

fioGender

string

Filter by gender (for fio suggestions).

  • 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

Filters for APIs that don't have dedicated options props,
like fms_unit, fns_unit, metro, mktu, okpd2, okved2, postal_unit, court.

To set filters for party_by and party_kz use entityStatus and entityType options, just like for normal party.

Component behavior

debounce

number

Delay (in ms) after changing the input (query) before sending the request.

Works on the principle of debounce: if the input continues to change,
the request will not be sent until this number of milliseconds has passed
since the last change.

Default 100

minChars

number

Minimum length of input after which suggestions are triggered.
Default 1

disabled

boolean

Sets the disabled attribute on the input element, disables suggestions and all interactions.
Default false

placeholder

string

Text used for the input's placeholder attribute.

inputName

string

Value for the input's name attribute.
Default dadata-input

inputAttributes

suggestionsHint

string

Text to show above the suggestions list

noSuggestionsHint

string | boolean

Text to show in place of suggestions when there are no suggestions. Pass true
if you use the hint slot for displaying a custom "no-suggestions" design to keep it visible.

classes

VueDadataClasses (object)

Custom CSS classes names for component elements.
Defaults: DEFAULT_CLASSES

showOnFocus

string | boolean

Controls when to show the dropdown with suggestions list on input focus.

  • false: Never show dropdown on focus
  • 'always': Always show dropdown on focus (if input and suggestions list is not empty).
  • 'no_selection': Show dropdown on focus when there's no selected suggestion

Default: 'no_selection'

selectOnBlur

boolean

If true, the first suggestion will be auto-selected after input lost focus.
Default: false

selectOnEnter

boolean

If true, pressing Enter selects the first suggestion (if list is open).
Default: true

enrichOnSelect

boolean

Whether to send an additional request after a suggestion is selected to enrich it with
data like geo_lat, geo_lon, city_district (and full value when restrictValue is used).

Set to false if you want to save API usage and don’t need that data.
Default: true

clearOnChange

string | boolean

Determines whether the suggestion (i.e., v-model:suggestion) is cleared when the input changes after a suggestion is selected.

  • false: The suggestion is never cleared when the input changes.
  • 'any': The suggestion is cleared whenever input value is changed.
  • 'significant': The suggestion is cleared only if the new input, after being normalized (i.e., trimmed and case-normalized), differs from the previous value.

Default: 'significant'

addSpace

boolean

If true, adds a space to the input after a suggestion is selected. This way, for example,
user can select street and then type house number without adding a space by himself.
Default true

continueSelecting

boolean

If true, the suggestions list will remain visible after selecting a suggestion.
Default: false

showClearButton

boolean

If true, shows a clear (×) button in the input when not empty.
Default: false

focusOnMounted

boolean

If true, input will be focused immediately when the component is mounted.
Default false

forceShow

boolean

Forces the suggestions list to always remain visible.
Useful during development (e.g., when styling elements).
Default: false

forceHide

boolean

Forces the suggestions list to always remain hidden.
Default: false

Emitted events

EventWhen emittedEvent payload type
@errorIn case of any errorunknown
@selectWhen a suggestion is selected, either by click, by pressing "Enter", or automatically when selectOnBlur=true(suggestion: object, selectType: string)
@enrichedWhen selected suggestion was enriched (when enrichOnSelect=true)(suggestion: object, diff: object | null)
@enrichFailWhen attemp to enrich selected suggestion fails (when enrichOnSelect=true)string (suggestion.unrestricted_value)
@focusWhen input is focusedFocusEvent
@blurWhen input looses focusFocusEvent

Slots

The props of each slot receive mergedClasses — an object containing all the CSS classes used by the component, in the same format as the object for the classes prop on the component (VueDadataClasses).

inputWrapper

A slot for replacing the main visible container with the input field, including the <input> and the “clear” button.

The following props are passed to the slot:

  • coreInputProps — recommended to v-bind fully to your own input. Includes essential event handlers required by the component: @input, @keydown, @focus, @blur, as well as the disabled attribute and value, which does not always match the text in query, as it may contain the currently visible text when navigating suggestions via keyboard.
  • browserAutoProps — attributes for disabling browser features that interfere with normal usage: autofill, autocomplete, autocorrect, and spellcheck.
  • allInputProps — includes everything from coreInputProps and browserAutoProps, plus the attributes type, class, name, and placeholder.
  • mergedClasses — the CSS classes used by the component.

Example usage:

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

If desired, <input> can be replaced with <textarea> (bind coreInputProps the props to it in the same way).

input

Replaces only the <input>, without affecting the parent container or the overlay with the “clear” button. The slot props are the same as for inputWrapper. Example:

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

inputOverlay

An empty slot that allows you to add custom elements inside the container with the input, such as a loading indicator, buttons, etc. There are no props except mergedClasses. Example:

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

clearButtonIcon

Replaces the icon of the built-in “clear” (×) button without affecting the <button> element itself. There are no props except mergedClasses. Example:

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

hint

This slot replaces the "hint" text shown above the suggestions list inside the dropdown and allows you to add custom elements to display there when suggestions are present, or instead of the list when nothing is found. For example, you can add a link or a button like "Reset filters," or apply custom styling to the suggestionsHint message (like “Choose an option or continue typing...”).

The container has @mousedown.prevent applied to prevent losing focus and hiding the dropdown when clicking inside the container.

To keep the dropdown visible when no suggestions are found, pass true to the component’s noSuggestionsHint prop.

Slot props:

  • suggestionsList — the current suggestions list
  • suggestionsHint — the hint text when suggestions are present (default or from the component's suggestionsHint prop)
  • noSuggestionsHint — the hint text when no suggestions are found (from the component's noSuggestionsHint prop)
  • mergedClasses — the CSS classes used by the component

Example:

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

<template #hint="{ suggestionsList, suggestionsHint, noSuggestionsHint }">
  <!-- Default message when suggestions are found -->
  <template v-if="suggestionsList.length"> {{ suggestionsHint }} </template>

  <!-- Custom block when no suggestions are available -->
  <template v-else>
    Nothing found...
    <button @click="reset">Reset filters?</button>
  </template>
</template>

suggestions

Replaces the entire suggestions list (without affecting hint and the dropdown container itself).

Slot props:

  • suggestionsList — an array of suggestion objects
  • navigatedIndex — the index of the navigated suggestion (when navigating via keyboard)
  • handleSuggestionClick — a click handler that must be added to each suggestion item to ensure full component functionality (add it with @mousedown.prevent="...")
  • mergedClasses — the CSS classes used by the component

Example:

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

suggestionItem

Replaces whole suggestion item (including its container).

Slot props:

  • suggestion — the suggestion object
  • index — the index of the item in the list (starting from 0)
  • isNavigated — whether this item is currently “highlighted” (during keyboard navigation)
  • handleSuggestionClick — a click handler that must be added to each suggestion item to ensure full component functionality (add it with @mousedown.prevent="...")
  • mergedClasses — the CSS classes used by the component

Example:

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

suggestionItemContent

Replaces the inner content of each suggestion item in the list, without affecting its parent container. The props are the same as for suggestionItem, except for handleSuggestionClick.

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

suggestionItemTitle

Replaces the element displaying the main text of the suggestion (suggestion.value). When using this slot, you’ll probably want to implement your own search text match highlighting — to get the highlighted chunks, you can use the highlightChunks function exported by the library.

The slot props are the same as for suggestionItem, except for 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

Replaces the element used to display additional text below the main suggestion text. The default slot content appears only in certain cases, such as suggestions for party or bank, but this slot allows you to show extra info at any time.

The props are the same as for suggestionItem, except for handleSuggestionClick.

vue
<template #suggestionItemSubtitle="{ suggestion, isNavigated }">
  <div class="...">{{ suggestion.data.inn }}</div>
</template>

Exposed Component API

The following methods and properties are available via the component's template ref (<VueDadata ref="vueDadata" ... />):

NameTypeDescription
inputRefShallowRef\<HTMLInputElement | null>\templateRef of the <input> element
suggestionsListRef<DadataSuggestion[], DadataSuggestion[]>The current list of suggestions or an empty array
isDropdownVisibleComputedRef<boolean>true when the suggestion list is visible
isFocusedComputedRef<boolean>true when the <input> is focused
update()(options) => DadataSuggestion[]Sends an API request and updates the suggestions list. You can pass options to override the ones set via props. Returns fetched suggestions list or throws on any error.
clear()() => voidClears the query text (modelValue), v-model:suggestion, and suggestionsList
show()() => voidShows the dropdown (if there are suggestions available)
hide()() => voidHides the dropdown
focus()() => voidFocuses the <input>
blur()() => voidRemoves focus from the <input>

Methods usage example

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>

Dependencies

Internal

Peer dependencies