
九保すこひです(フリーランスのITコンサルタント、エンジニア)
さてさて、私は運がいいことにいつもご配慮をいただけるクライアント様方からご依頼をいただいています。
そして、ご依頼をいただいた方々にはできる限り
- おっ、これ便利だね
- これで楽になるよ
と感じてもらえたら、と考えています。
つまり、「ユーザビリティ」の部分ですが、先日リサーチしていると、とても便利に使えるVue
コンポーネント「Vue Select」を発見しました。
機能としては、jQuery
の select2 のように「入力候補がついているセレクトボックス」で、とてもシンプルに使えるのが特徴です。
(実は似たものは発見してたんですが、毎回「なんだか複雑だな・・・だったら、時間ができたら自分でつくろうかな」なんて考えてました)
ということで、今回は「Vue Select」をLaravelで使う方法、そして各種設定方法をご紹介します。
ぜひ皆さんのお役にたてると嬉しいです
まずは、デモページで体験してみてください。
「これまでは、Vue & select2
を連携させてました」
開発環境: Laravel 7.x(デモページは 5.8)、vue-select 3.10.7
目次 [非表示]
Vue Selectをインストールする
まずはnpm
を使ってVue Select
をインストールします。
npm install vue-select
※ なお、「npmは難しいからヤダ」という方はCDNを使うバージョンをご覧ください。
webpackでコンパイルする
続いて、webpack
を使ってVue Select
をコンパイルします。
Laravel
にはwebpack
を使う環境が整っていますので、まずnpm install
を実行してから以降の手順を試してみてください。
JavaScriptの設定
では、まずJavaScript
の設定です。
以下のようにコードを変更してください。
/resources/js/app.js
// 省略
require('./bootstrap');
window.Vue = require('vue');
Vue.component('v-select', require('vue-select').default); //
追加
//
不要な部分はコメントアウト
// const files = require.context('./', true, /\.vue$/i)
// files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default))
// Vue.component('example-component', require('./components/ExampleComponent.vue').default);
// const app = new Vue({
// el: '#app',
// });
CSSの設定
続いてCSS
です。
同じくvue-select.scss
を呼び出せるようにコードを追加してください。
/resources/sass/app.scss
// Fonts
@import url('https://fonts.googleapis.com/css?family=Nunito');
// Variables
@import 'variables';
// Bootstrap
@import '~bootstrap/scss/bootstrap';
// Vue Select
@import 'vue-select/src/scss/vue-select.scss'; //
追加
webpackでコンパイルする
コードの準備が完了したら、以下のコマンドでコンパイル(トランスパイル)をしましょう。
npm run dev
もしくは、本番環境用のこちら。
npm run production
これで、JavaScript
とCSS
はそれぞれ以下のファイルにまとめられました。
- /public/js/app.js
- /public/css/app.css
使い方
ではVue Select
の実際の使い方です。
基本的な使い方
基本的にはタグを用意して選択肢を:options
に入れるだけでOKです。
<html>
<head>
<link rel="stylesheet" href="{{ mix('css/app.css') }}">
</head>
<body>
<div id="app" class="p-3">
<h1>Laravel + Vue Select サンプル</h1>
<div class="row">
<div class="col-3">
<v-select :options="options" v-model="name"></v-select>
</div>
</div>
<div class="pt-2">
選択されているデータ: <span v-text="name"></span>
</div>
</div>
<script src="{{ mix('js/app.js') }}"></script>
<script>
new Vue({
el: '#app',
data: {
name: '',
options: [
'太郎',
'次郎',
'三郎',
'花子'
]
}
});
</script>
</body>
</html>
もちろんv-model
をセットすればリアルタイム・バインディングに対応してくれます。
デモページはこちら。
選択肢にコレクションを使う場合
次に選択肢を単なる配列ではなく、コレクション(オブジェクトの配列)を使う場合です。
Vue Select
では、label
が選択肢として表示されるキーになります。
new Vue({
el: '#app',
data: {
name: '',
//
label をセットする
options: [
{ id: 1, label: '太郎' },
{ id: 2, label: '次郎' },
{ id: 3, label: '三郎' },
{ id: 4, label: '花子' },
]
}
});
ちなみに選択肢が選ばれた場合、変数の中身は次のようになります。
デモページはこちら。
なお、もし選択されたデータを絞り込みたい場合は:reduce
を使ってください。
<v-select
label="name"
:options="options"
:reduce="user => user.id"
v-model="name"></v-select>
実行結果はこうなります。
選択肢のコレクションが独自のキーの場合
選択肢のコレクションにlabel
が入っていなくても、代わりに任意のデータを表示させることができます。
例えば、DB
からデータ取得する場合のデータ構造は以下のようになっています。
new Vue({
el: '#app',
data: {
name: '',
options: [
{ id: 1, name: '太郎' },
{ id: 2, name: '次郎' },
{ id: 3, name: '三郎' },
{ id: 4, name: '花子' },
]
}
});
この場合は、タグの中にlabel="*****"
というプロパティを追加してあげるだけで選択肢のキーを変更することができます。
<!--
options.name の内容を表示 -->
<v-select label="name" :options="options" v-model="name"></v-select>
先ほどと同じく、実際に選択されたときは該当するオブジェクトが変数として使われます。
デモページはこちら。
CDNでもっと簡単に使いたい場合
もしnpm
を使わずにVue Select
を使いたい場合は次のようにcdn
が使えます。
<html>
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://unpkg.com/vue-select@latest/dist/vue-select.css">
</head>
<body>
<div id="app" class="p-3">
<h1>CDNを使った Vue Select サンプル</h1>
<div class="row">
<div class="col-3">
<v-select :options="options" v-model="name"></v-select>
</div>
</div>
<div class="pt-2">
選択されているデータ: <span v-text="name"></span>
</div>
</div>
<script src="https://unpkg.com/vue@latest"></script>
<script src="https://unpkg.com/vue-select@latest"></script>
<script>
//
ここでコンポーネント有効化
Vue.component('v-select', VueSelect.VueSelect);
new Vue({
el: '#app',
data: {
name: '',
options: [
'太郎',
'次郎',
'三郎',
'花子'
]
}
});
</script>
</body>
</html>
各種設定方法
Vue Select
はシンプルに使えるだけでなく、色々な設定をするとさらに便利になりますので特におすすめのものをご紹介します。
複数選択できるようにする
なんとVue Select
は複数選択に対応しています。
しかもタグにmultiple
をつけるだけで以下のようになります。
コードはこうなります。
<v-select multiple label="name" :options="options" v-model="names"></v-select>
new Vue({
el: '#app',
data: {
names: [], //
変更
options: [
'太郎',
'次郎',
'三郎',
'花子',
]
}
});
※複数選択なので、names
として初期値を配列に変更しています。
さらに、multiple
に加えて次のプロパティを追加するとさらに機能を強力にできますよ!
- taggable: 選択肢には入っていないものも入力でセットできるようになる
- push-tags: taggableで入力されたものが自動で選択肢に入る
アイコンを変更する
セレクトボックスに使われるアイコンを変更することができます。
/resources/js/app.js
let vSelect = require('vue-select').default;
vSelect.props.components.default = () => ({
Deselect: {
render: createElement => createElement('span', '✕'),
},
OpenIndicator: {
render: createElement => createElement('span', '▼'),
},
});
Vue.component('v-select', vSelect);
※CDNバージョンは直接セットしてください。
これを実行するとこのように変更になります。
日本語化
Vue Select
は初期状態では選択肢が見つからないとき「Sorry, no matching options.」と英語でメッセージを表示しますが、これを日本語化するには以下のようにします。
<v-select :options="options" v-model="name">
<template #no-options>
選択肢が見つかりません。
</template>
</v-select>
これを実行するとこうなります。
独自の選択肢をつくる
独自の形式で選択肢を表示したい場合には、#option={ *** }
を使います。
<v-select :options="options" v-model="name">
<!--
独自の選択肢をつくる -->
<template #option="{ id, name }">
<span v-text="name"></span> さん(ID: <span v-text="id"></span>)
</template>
</v-select>
new Vue({
el: '#app',
data: {
name: '',
options: [
{ id: 1, name: '太郎' },
{ id: 2, name: '次郎' },
{ id: 3, name: '三郎' },
{ id: 4, name: '花子' },
]
}
});
これを実行するとこうなります。
Ajaxでリアルタイム検索して選択肢を取得する
例えば、Laravel
で作成した以下のユーザーから選択肢を取得してみましょう。
まずタグに用意するのが@search="*****"
です。
これは、セレクトボックスが変更されると設定したメソッドを実行してくれるイベントです。
以下の例では、getusers()
が実行されることになります。
<v-select
label="name"
:options="options"
@search="getUsers"
v-model="name"></v-select>
次にAjax
部分です。
今回はaxios
で実行します。
new Vue({
el: '#app',
data: {
name: '',
options: []
},
methods: {
getUsers(search, loading) {
loading(true); // ローダー(くるくる回るアイコン)を表示開始
const url = '/search_users?keyword='+ search;
axios.get(url)
.then(response => {
this.options = response.data;
})
.catch(error => {
// エラーがあった場合の処理
})
.finally(() => {
loading(false); // ローダーを消す
});
}
}
});
そして、最後にLaravel
でDB
からデータを取得するのは次のようになります。(ルート部分は省略しています)
<?php
// 省略
class HomeController extends Controller
{
public function search_users(Request $request) {
return \App\User::where('name', 'LIKE', '%'. $request->keyword .'%')
->take(10) // 選択肢が多くなりすぎないように最大件数を決めておくといいかもしれません
->get();
}
// 省略
これを実行するとこうなります。
おわりに
ということで、今回はユーザビリティを向上させることができるVueコンポーネント「Vue Select」をご紹介しました。
基本的な使い方をするだけでしたら、とてもシンプルなコードで実装できるのできっと使いやすいと思います。開発をされているJeff Sagal
さんには感謝あるのみですね
ぜひ皆さんもこのパッケージを活用して使いやすいシステムを開発してみてくださいね。
ではでは〜
「ついに田舎の我が町にも
ストリートピアノが設置されたので
用もないのに出かけてきました」