Laravel 5.5
axios ^0.17
vue ^2.5.7
を使用します。
Model
Postモデルがあるとします。
フィールドもいろいろあると思いますが、今回はtitleで検索します。
app/Models/Post.php
namespace App\Models; use Illuminate\Database\Eloquent\Model; class Post extends Model { protected $fillable = [ 'title', 'body' ]; }
Router
ルーターはroutes/api.php
に設定すると、api/posts
みたいにアクセスして取得できるようになります。
routes/api.php
Route::get('posts', 'Api\PostsController@index');
Controller
URLにパラメータがない場合は空の配列を返して、title
パラメータがあった場合のみ検索されるようにします。
Http/Controllers/Api/PostsController.php
namespace App\Http\Controllers\Api; use App\Http\Controllers\Controller; use App\Models\Post; use Illuminate\Support\Facades\Input; class PostsController extends Controller { public function index() { if (!empty(Input::get('title'))) { $queryTitle = Input::get('title'); return Post::select('id', 'title') ->where('title', 'LIKE', "%$queryTitle%") ->limit(20)->get(); } return []; } }
これで/api/posts?title=検索ワード
のようにアクセスすることでtitleに検索ワードが含まれるレコードを返すような作りができました。
Vue.jsコンポーネント作成
新たにPostSearchComponent
という名前でコンポーネントを作成します。
resources/assets/js/components/PostSearchComponent.vue
<template> <div> <input type="text" v-model="keyword"> <div class="result-view"> <ul> <li v-for="post in posts"> {{ post.title }} </li> </ul> </div> </div> </template>
<script> export default { data() { return { keyword: "", posts: {} } }, methods: { search() { axios.get('/api/posts?title=' + this.keyword) .then(res => { this.posts = res.data; }) .catch(error => { console.log('データの取得に失敗しました。'); }); } }, watch: { keyword() { this.search(); } } } </script>
Vue.jsのイベントでkeyupというのがあり、これでキーボードで入力したときにイベントを発火できるのですが、漢字の変換でもイベントが実行されてしまいます。
なので、watch
にposts
を登録して、この変数が書き換えられたときイベントが発生するようにします。
次に、app.js
に作成したコンポーネントを登録します。
resources/assets/js/app.js
Vue.component('post-search', require('./components/PostSearchComponent.vue'));
最後にLaravelで表示させたいViewに登録したコンポーネントを追記しましょう。
resources/views/js/xxxx.blade.php
<post-search></post-search>