Laravel バージョン6.x〜で Vue.jsを利用し、またAxiosでJSONデータを取得してみます。
まずlaravel/uiパッケージをインストールします。
1 |
$ composer require laravel/ui |
Vue.jsで構築するためのファイル等を生成します。
1 2 3 4 |
$ php artisan ui vue Vue scaffolding installed successfully. Please run "npm install && npm run dev" to compile your fresh scaffolding. |
ルートディレクトリにあるpackage.jsonのdevDependencies項目にvue等が追記されているのが確認できます。
1 2 |
"vue": "^2.5.17", "vue-template-compiler": "^2.6.10" |
package.jsonの内容に依存したパッケージをインストールし、コンパイルします。
1 |
$ npm install && npm run dev |
Vueコンポーネント(後述)関連のファイルを編集/保存した際には「npm run dev」で再度コンパイルする必要がありますが、watchでそれら編集/保存を監視しコンパイルを自動化することができます。
1 |
$ npm run watch |
サーバーを起動させます。
1 |
$ php artisan serve |
ルートディレクトリにあらかじめLaravelで用意されているwebpack.mix.jsがありますが、これはwebpackのラッパーであるLaravel Mixの設定用ファイルです。
webpack.mix.jsに下記のような記述がありますが、resources/js/app.jsはコンパイルされpublic/jsディレクトリに、resources/sass/app.scssはコンパイルされpublic/cssディレクトリに出力されるよう設定されています。
1 2 |
mix.js('resources/js/app.js', 'public/js') .sass('resources/sass/app.scss', 'public/css'); |
またapp.jsにはすでにVueコンポーネントが登録されているのが確認できます。
resources/js/app.js
1 |
Vue.component('example-component', require('./components/ExampleComponent.vue').default); |
example-componentという名前のコンポーネントに対して、componentsディレクトリ以下にあるExampleComponent.vueファイル(後述)が割り当てられています。つまりExampleComponent.vueを利用する場合はexample-componentコンポーネントタグをLaravelのビュー(テンプレート)側に記述します。コンポーネントを作成したらこのようにapp.jsに記述していきます。
コンポーネント自体については関連ページをご覧下さい。
生成されたcomponentsディレクトリ内にあるExampleComponent.vueファイルを確認してみます。Laravelではこのcomponentsディレクトリ内にVueコンポーネントを配置していきます。
resources/js/components/ExampleComponent.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<template> <div class="container"> <div class="row justify-content-center"> <div class="col-md-8"> <div class="card"> <div class="card-header">Example Component</div> <div class="card-body"> I'm an example component. </div> </div> </div> </div> </div> </template> <script> export default { mounted() { console.log('Component mounted.') } } </script> |
単純に文字列と、ログが出力されるだけのコンポーネントです。
実際にこのExampleComponent.vueコンポーネントを利用してみます。すでに存在するトップ画面に表示させてみます。welcome.blade.phpに下記コードを追記します(ハイライト部分)。
resources/views/welcome.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
~省略 .m-b-md { margin-bottom: 30px; } </style> <link href="{{ mix('css/app.css') }}" rel="stylesheet" type="text/css"> </head> ~省略 <div class="links"> <a href="https://laravel.com/docs">Docs</a> <a href="https://laracasts.com">Laracasts</a> <a href="https://laravel-news.com">News</a> <a href="https://blog.laravel.com">Blog</a> <a href="https://nova.laravel.com">Nova</a> <a href="https://forge.laravel.com">Forge</a> <a href="https://vapor.laravel.com">Vapor</a> <a href="https://github.com/laravel/laravel">GitHub</a> </div> </div> </div> <div id="app"> <example-component></example-component> </div> <script src="{{mix('js/app.js')}}"></script> </body> </html> |
7行目
Laravel Mixのコンパイルによって出力されたアセットをLaravelのグローバル関数であるmix()を利用して読み込んでいます。
24〜27行目
resources/js/app.jsにおいてVueインスタンスのelオプションに指定されているid名がappのdivを用意し、その中に「example-component」コンポーネントタグを記述しています。コンパイルによって出力されたアセットは<div id=”app”>〜</div>の後に読み込みます。
画面下にコンポーネントが表示されたのが確認できました。
Axiosを利用する
新たに画面を作成しAxiosを利用してJSONデータを表示させてみます。JSONはモックデータを提供するサービスであるJSONPlaceholderを利用しています。
コントローラーを作成し、ルート情報に追記、後述のようにコントローラーを編集します。Laravelの通常の手順ですので説明は省きます。
1 |
$ php artisan make:controller TodoController |
routes/web.php
1 |
Route::get('/todo', 'TodoController@index'); |
app/Http/Controllers/TodoController.php
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class TodoController extends Controller { public function index() { return view('todo.index'); } } |
ビュー(テンプレート)を作成します。todoディレクトリおよびindex.blade.phpをを作成し下記のように記述します。
resources/views/todo/index.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<!DOCTYPE html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <head> <meta charset="UTF-8"> <title>Axiosサンプル</title> <meta name="csrf-token" content="{{ csrf_token() }}"> </head> <body> <div id="app"> <todo-component></todo-component> </div> <script src="{{ mix('js/app.js') }}"></script> </body> </html> |
7行目
本記事では必要ありませんが、フォーム等を利用する場合はCSRF対策をする必要があります。
app.jsに下記コードを追記して下さい。
resources/js/app.js
1 |
Vue.component('todo-component', require('./components/TodoComponent.vue').default); |
todo-componentという名前のコンポーネントに対してTodoComponent.vueを割り当てます。
TodoComponent.vueを作成し下記のように記述します。
resources/js/components/TodoComponent.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
<template> <div> <p v-if="errored">{{ error }}</p> <p v-if="loading">Loading...</p> <div v-else> <ul> <li v-for="todo in todos" :key="todo.id">{{ todo.title }}</li> </ul> </div> </div> </template> <script> export default { data() { return { loading: true, errored: false, error: null, todos: null }; }, created() { let vm = this; axios .get("https://jsonplaceholder.typicode.com/todos", { params: { userId: "1" } }) .then(response => { vm.todos = response.data; }) .catch(err => { (vm.errored = true), (vm.error = err); }) .finally(() => (vm.loading = false)); } }; </script> |
Axios自体の説明については下記ページをご覧下さい。
/todo 画面
参照ページ
Laravel 6.x JavaScriptとCSSスカフォールド