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>
