今回はVue.jsでテキスト検索(絞り込み)機能を実装してみました。ソースはコピペで動きます。もし不明な点や質問、ご指摘がありましたら、記事下のフォームからコメントをお願いします。

実際の挙動と仕様

当機能の仕様は、何らかの飲食店のリストがあったと仮定して、ユーザーが自分の興味のある検索ワード(例:焼肉、五反田)で検索した際に、入力欄にマッチするレコードのみを表示させるもの。

動作は、下記JSFiddleの「Result」からご確認いただけます。

ユーザーがテキスト入力欄に検索テキストを入力して、フォーカスが外れたタイミングで検索処理を実行しています。検索対象は、店舗コード・店舗名・エリアの3つの項目になっており、JavaScriptのfilter()を使用して一致のチェックを行なっています。

コード解説

実際に、テキストでの絞り込み検索を実装する上でどのような処理が行われているのかを解説します。

HTML

<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<div id="app">
  <div>
    <input
      type="text"
      v-model.trim="search_text"
      @change="search()"
      placeholder="検索テキスト"
    >
  </div>
  <table>
    <thead>
      <tr>
        <td>店舗コード</td>
        <td>店舗名</td>
        <td>エリア</td>
      </tr>
    </thead>
    <tbody>
      <tr
        v-for="(item, i) in search_items"
        :key="i"
      >
        <td>{{ item.cd }}</td>
        <td>{{ item.name }}</td>
        <td>{{ item.area }}</td>
      </tr>
    </tbody>
  </table>
</div>

HTMLの重要ポイントは下記の3つ。

  • @change=”search()” : inputの入力値が変更されたタイミングで検索処理を実行
  • v-model.trim=”search_text” : 検索ワード(半角スペースなどの不要な余白はv-model.trimで削除する)をdataプロパティで定義
  • v-for=”(item, i) in search_items” : this.shops(店舗一覧)をループ対象にするのではなく、search_itemsという新たな配列に検索結果を格納し描画する。元データには変更を加えたくないので。

Vue.js

new Vue({
	el: "#app",
  data: {
  	shops: [
    	{ cd: "sbjhv7876xah", name: "焼肉食べ放題サンプル店舗", area: "五反田" },
      { cd: "f763fgw7iucs", name: "中華食べ放題サンプル店舗", area: "神田" },
      { cd: "cvgmnoq09vjd", name: "寿司食べ放題サンプル店舗", area: "神保町" },
      { cd: "83487wvsbdsy", name: "和食食べ放題サンプル店舗", area: "八王子" },
      { cd: "01e0284yf9xj", name: "洋食食べ放題サンプル店舗", area: "錦糸町" },
    ],
    search_text: "",
    search_items: [],
  },
  created() {
  	this.search()
  },
  methods: {
  	search() {
    	let items = this.shops
    	if(this.search_text) {
        items = items.filter(
          (v) =>
            v.cd.includes(this.search_text) ||
            v.name.includes(this.search_text) ||
            v.area.includes(this.search_text)
        )
      }
      this.search_items = items
    }
  }
})

JavaScriptについては、検索処理順に解説を行います。

search()

検索ワードが入力された場合、まず変数(let items)にthis.shops(店舗情報)を代入します。

次に、検索ワード(this.search_text)にマッチするレコードが存在するかチェックします。

検索ワードチェックは、JavaScriptのfilter()を使用します。

filter()は、テスト(検索ワードチェック)に合格した全ての配列から新しい配列を生成するメソッドなので、今回の場合だと、店舗コード(cd)、店舗名(name)、エリア(area)ごとに検索ワードをテストし、検索ワードにマッチする配列が変数itemsに格納されるようになります。

例えば「焼肉」という検索ワードを入力した際に、filter()のテストに合格した配列は下記です。よって検索結果は1レコードのみの表示になります。

{ cd: “sbjhv7876xah”, name: “焼肉食べ放題サンプル店舗”, area: “五反田” },

そして最終行程で、filter()を通過して帰ってきた配列をthis.search_itemsに代入します。

これでリストのテキスト検索での絞り込み機能が実装できます。

created()の処理について

上記のVue.jsのソースを見ていると、created()でsearch()が実行されていると思います。これは、リストのループ処理に使用しているdataプロパティsearch_itemsに、初期値をセットするために実行しています。

includes()

filter()の内部で、入力値とのマッチをチェックするためにincludes()を使用しました。

includes() メソッドは、特定の要素が配列に含まれているかどうかを true または false で返します。テキスト検索は部分一致でも結果を返す方が使いやすいので、includes() メソッドが適切ではないかと判断しました。

includes() メソッドについて

カテゴリー: Vue.js