【Vue.js】Element Uiでautocompleteのサジェスト機能を導入する方法と使い方!

この記事からわかること

  • Vue.jsElement Uiの機能
  • autocomplete導入方法使い方
  • v-modelリンクづける方法

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

豊富なコンポーネントと導入のしやすさから人気のVue.jsのUIライブラリの1つ「Element Ui」。

その中の「autocomplete」を使おうとした際に試行錯誤した部分と導入方法、使い方も併せてまとめておきます。

Element Uiでautocompleteを導入しよう!

Element Uiで使えるボタンコンポーネント

Element Ui

Element Ui自体の導入方法はここでは割愛します。詳しくはこちらの記事をご覧ください。

ライブラリの導入ができたら「autocomplete」を使用できるように設定をしていきます。プロジェクトの中の「src」>「plugins」>「element.js」に追記していきます。

オンデマンドインストールの「element.js」

import Vue from 'vue'
import {
    Alert,
    Input,
    Dialog,
    Autocomplete, // 追加
} from 'element-ui'
import lang from 'element-ui/lib/locale/lang/ja'
import 'element-ui/lib/theme-chalk/index.css';
import locale from 'element-ui/lib/locale'

locale.use(lang)
const components = [
    Alert,
    Input,
    Dialog,
    Autocomplete, // 追加
];

const Element = {
    install(Vue) {
        components.forEach(component => {
            Vue.component(component.name, component)
        })
    }
}
Vue.use(Element, { locale })

オンデマンドインストールでのElement Uiでは「element.js」に使いたいコンポーネントを追加していくだけでOKです。これで<el-autocomplete>タグが使用可能になりました。

el-autocompleteの使い方と特徴

Element Ui:autocomplete

el-autocompleteはinput要素にサジェスト(入力アシスト)機能を追加できるコンポーネントです。

使用方法は簡単で公式ページのデモコードをそのままコピペして貼り付けるだけで動作してくれます。そのままコピペすると2つのタイプのautocompleteが動きます。

  1. Input要素をアクティブ時に全てのサジェストが出るタイプ
  2. 入力された文字を識別して該当のサジェストが出るタイプ

公式ページのデモコード

<el-row class="demo-autocomplete">
  <!-- タイプ1 --> 
  <el-col :span="12">
    <div class="sub-title">list suggestions when activated</div>
    <el-autocomplete
      class="inline-input"
      v-model="state1"
      :fetch-suggestions="querySearch"
      placeholder="Please Input"
      @select="handleSelect"
    ></el-autocomplete>
  </el-col>
  <!-- タイプ2 -->  
  <el-col :span="12">
    <div class="sub-title">list suggestions on input</div>
    <el-autocomplete
      class="inline-input"
      v-model="state2"
      :fetch-suggestions="querySearch"
      placeholder="Please Input"
      :trigger-on-focus="false"
      @select="handleSelect"
    ></el-autocomplete>
  </el-col>
</el-row>
<script>

  export default {
    data() {
      return {
        links: [],
        state1: '',
        state2: ''
      };
    },
    methods: {
      querySearch(queryString, cb) {
        var links = this.links;
        var results = queryString ? links.filter(this.createFilter(queryString)) : links;
        // call callback function to return suggestions
        cb(results);
      },
      createFilter(queryString) {
        return (link) => {
          return (link.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0);
        };
      },
      loadAll() {
        return [
          { "value": "vue", "link": "https://github.com/vuejs/vue" },
          { "value": "element", "link": "https://github.com/ElemeFE/element" },
          { "value": "cooking", "link": "https://github.com/ElemeFE/cooking" },
          { "value": "mint-ui", "link": "https://github.com/ElemeFE/mint-ui" },
          { "value": "vuex", "link": "https://github.com/vuejs/vuex" },
          { "value": "vue-router", "link": "https://github.com/vuejs/vue-router" },
          { "value": "babel", "link": "https://github.com/babel/babel" }
         ];
      },
      handleSelect(item) {
        console.log(item);
      }
    },
    mounted() {
      this.links = this.loadAll();
    }
  }
</script>

デフォルトで用意されているメソッドとその役割と意味は以下の通りだと思います。

メソッドの意味

サジェストデータをAPIで取得させる

実際にデモコードを使ってカスタマイズしてみます。今回はAPIで連想配列を取得しサジェストのデータに組み込んでいきます。

Laravelのweb.phpとコントローラーを編集しURL/api/categoryで以下のような連想配列を返すように設定しておきます。

{"category_id":1,"value":"食事"},
{"category_id":2,"value":"スポーツ"},
{"category_id":3,"value":"読書"},
{"category_id":4,"value":"住まい"},
{"category_id":5,"value":"子供"},
{"category_id":6,"value":"お金"},
{"category_id":7,"value":"生活"}....

web.php

Route::post('/api/category', 'App\Http\Controllers\ApiController@category');

ApiController

public function category()
{
  $category = DB::select('SELECT * FROM category');
  return $category;
}

今回はデータベースに格納しているカテゴリテーブルの全値を取得させています。

続いてVuexを使って管理している「src」>「store」>「index.js」に以下のように記述します。

export default new Vuex.Store({
    strict: true,
    state: {
        links: [],
    },
    mutations: {
      getCategory(state, api) {
            state.links = api;
        },  
    }.
    actions: {
    async callCategory(context) {
          const response = await axios.post("/api/category");
          context.commit('getCategory', response.data);
    }
}

これで$store.state.linksでAPIで取得している連想配列に参照することができます。

今回はサジェストで選択された連想配列値のcategory_idをdataのcategory_idに格納するのを目標にしていきます。

<template>
    <el-autocomplete
      v-model="category"
      :fetch-suggestions="querySearch"
      placeholder="カテゴリ"
      :class="{err:err.category}"
      @select="checkPost"
      @blur="checkPost"
      ></el-autocomplete>
      <!-- サジェストから選択された時 @select-->  
      <!-- フォーカスが外れた時 @blur-->  
</template>

<script>
export default {
    data() {
      return {
        category: "",
        category_id: "",
        err:{
          category:false,
        },
      };
    },
    computed: {
      links() {
        return this.$store.state.links;
      },
    },
    methods: {          
      querySearch(queryString, cb) {
        var links = this.links;
        var results = queryString
          ? links.filter(this.createFilter(queryString))
          : links;
        // call callback function to return suggestions
        cb(results);
      },
      createFilter(queryString) {
        return (link) => {
          return (
            link.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0
          );
        };
      },
      checkPost(item){
        if(item.value !==  undefined){
            this.category = item.value
        }
          if(this.category !== ""){
            const target = this.links.find((data)=> {return (data.value === this.category)});
              if(target === undefined){
                this.err.category= true;
              }else{
                // 選択された正しいカテゴリidを格納
                this.category_id =target.category_id;
                this.err.category= false;
              };
        }

      },
    },
};
</script>

v-on(@)サジェストから選択された時とフォーカスが外れた時のイベントを補足し、checkPostを呼び出します。

checkPost引数に変数を渡せば、選択されたサジェストのidとvalueを受け取ることができます。

v-modelを使ってinput要素のvalue属性とdata変数の中身をリンクさせようとしましたがサジェストで選択された値はv-modelの中には自動で格納されないようでした。

なので47行目の部分でdata変数の中に入れ込んでおく必要がありました。

if(item.value !==  undefined){
  this.category = item.value
}

実際にElement Uiを使って作ったのが以下のwebアプリです。サジェスト機能も使っているので除いてみてください!

子育て知識共有サイト-mikata- 子育て知識共有サイト-mikata-

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index