Help us understand the problem. What is going on with this article?

[Vue.js] サジェスト/自動補完(autocomplete)を行うコンポーネント

はじめに

Vue.jsで、某大手検索エンジンのような、サジェストリストを表示する入力コンポーネントを作成しました。npmで公開していますので、良かったら使ってやってください。

どんな機能

テキストボックスに文字を途中まで入力すると、残りの候補をサジェスト表示(自動補完)する機能を持つVue.jsのテキストボックスコンポーネントです。検索エンジンのサイトなどでよく見かけるあれです。

以下のGIFアニメを見てもらえれば、一発でどんなコンポーネントかが分かると思います。

サジェスト入力動画.gif

シンプルなサンプル

とにもかくにも、サンプルコードです。data()で指定した配列をサジェストリストに表示するシンプルなサンプルです。

<template>
  <div style="width:400px">
    <vue-suggest-input v-model="selected" :items="items"/>
  </div>
</template>
<script>
import VueSuggestInput from 'vue-suggest-input'
import 'vue-suggest-input/dist/vue-suggest-input.css'

export default {
  components: {
    VueSuggestInput
  },
  data() {
    return {
      items: ['apple','cocoa','coffee','cola'],
      selected: "",
    }
  }
}
</script>

実際の運用ではREST APIなどで、外部からサジェストリストに表示する内容をロードすると思いますが、その方法は後述。

インストール

npmでインストールできます。

npm i vue-suggest-input --save

キーボードショートカット

ショートカットキーで、サジェストリストの表示や、リスト内の移動・選択が行えます。

サジェストリストが非表示の時

Key 説明
上矢印(↑)、下矢印(↓) サジェストリストを表示します
Enter searchイベントを発生させます。

サジェストリストが表示されている時

Key 説明
Escape(ESC) サジェストリストを閉じます。
上矢印(↑) 候補の選択を上に移動します。
下矢印(↓) 候補の選択を下に移動します。
Enter サジェストリストで選択した候補を入力エリアに設定し、searchイベントを発生させます。

プロパティ (Props)

items

型: Array or Function or Promise
デフォルト値: null

概要

サジェストに表示する文字列(String)を配列を指定します。配列、関数、Promiseのいずれかの型を指定します。関数またはPromiseで指定する場合、関数からの戻り値は配列(Array)である必要があります。

  • 配列で指定する場合の例
<vue-suggest-input :items="['item1', 'item2']"/>
  • Promiseを指定する場合の例
template
<vue-suggest-input :items="getItems"/>
javascript
export  default {
  methods: {
    async getItems() {
      const { data } = await this.$axios.get("url")    
      return data
    }
  }
}

filter-func

型: Function
デフォルト値: null

概要

サジェストの内容をフィルタ処理するためのカスタム関数を指定できます。カスタム関数には2つ引数が渡されます。引数の1つ目は、フィルタを行うサジェストの内容、2つ目は入力エリアの内容が渡されます。

カスタム関数はbool型の戻り値を返す必要があります。trueを返した場合、1つ目の引数のサジェストが候補として表示されます。falseを返した場合は表示されません。

下のサンプルコードは、サジェストに11の文字列を含むものだけを、候補のリストに表示するようになっています。

template
<vue-suggest-input 
  :item="['item011', 'item012', 'item111']"
  :filter-func="myFilter"/>
javascript
export  default {
  methods: {
    myFilter(suggestItem, inputValue) {
      return suggestItem.indexOf("11") >= 0
    }
  }
}

max-suggest

型: Number
デフォルト値: 10

概要

表示するサジェストの最大数を指定します。

template
<vue-suggest-input :max-suggest="5"/>

query-interval

型: Number
デフォルト値: 100

概要

サジェストリストを再検索する間隔をミリ秒単位で設定します。例えば1000を指定した場合、1秒感覚でitemsプロパティに指定した配列または関数から、サジェストの検索を行います。

逆に、入力の度にすぐに候補の検索を行いたい場合は0を指定します。

template
<vue-suggest-input :query-interval="1000"/>

loading-show-delay

型: Number
デフォルト値: 500

概要

サジェストの検索中に、「読み込み中…」の表示を行うまで時間をミリ秒単位で指定します。例えば500を指定した場合、サジェストの検索に500ミリ秒以上の時間を要している場合、入力欄の下に「読み込み中…」の表示が行われます。

サジェストの検索に時間を要する場合に有用なプロパティです。

イベント

search

サジェストリストから候補を選択した時や、Enterキーで入力を確定させた時に発生するイベントです。主にこのコンポーネントに入力された検索条件をもとに、メインの検索処理を行うようような場合に使用します。

template
<vue-suggest-input @search="doSearch()"/>

input

入力の度に発生するイベントです。これはHTMLElementinpputイベントと等価です。

template
<vue-suggest-input @input="doInput()"/>

アイコンのカスタマイズ

入力エリア右のアイコンを、独自のアイコン等に置き換えることができます。デフォルトでは、下の画像のような、虫眼鏡のSVGアイコンが表示されます。

入力エリア右のアイコン

アイコンのカスタマイズには、slotを使います。以下がサンプルコードです。

slotでアイコンを置き換えるサンプル
<vue-suggest-input>
  <div slot="add-on-icon">
    <i class="fa fa-rocket" aria-hidden="true"></i>
  </div>
</vue-suggest-input>

上のコードの場合、次のイメージのようにアイコンがslotで指定したものに置きかわります。

アイコンカスタマイズ後の画面イメージ

サジェスト項目のカスタマイズ

defaultスロットに、カスタマイズのHTMLを設定すると、サジェスト項目のデザインをカスタマイズする事ができます。

<vue-suggest-input>
  <template slot-scope="{text}">
    <div>
      <i class="fa fa-code" aria-hidden="true"></i>
      <span>{{text}}</span>
    </div>
  </template>
</vue-suggest-input>

【実行結果】
カステムサジェストの実行結果

さいごに

バグ等あれば、コメントで教えてもらえたら喜びます。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away