環境
- Laravel: 8.6.2
- Vue.js: 2.6.12
- PHP: 8.0.8
- Composer: 2.5.1
- Node.js: 19.3.0
$ composer create-project --prefer-dist laravel/laravel:^8.0 project-name
$ cd project-name
$ php artisan migrate:fresh
$ composer require laravel/ui
$ php artisan ui vue --auth
$ npm install && npm run dev
$ php artisan serve
--auth
とするとViewが用意されていて楽なので、この記事では既に用意されているhome.blade.phpに追記する形で、動かしていきたいと思います。
Tips.認証機能の無効化
環境構築時にphp artisan ui vue --auth
としたのは、新たに追加されるapp.blade.phpとhome.blade.phpを使うためです。
しかし、一々このためにregister,login処理をするのも面倒なので、以下のコードをコメントアウトしておくとURLに/home
と入力するだけで検証結果が確認できるようになります。
Route::get('/', function () {
return view('welcome');
});
// Auth::routes(); <- コメントアウト
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
public function __construct()
{
// $this->middleware('auth'); <- コメントアウト
}
1.resource/views/layouts/app.blade.phpにyieldを追加する
そこでhome.blade.phpを見てみると、layouts.appを継承していることがわかるので、継承元のlayouts.appにscriptを記述するためのyieldを追加します。
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
~~~~
<main class="py-4">
@yield('content')
</main>
</div>
@yield('js') <-- ここに追加
</body>
</html>
なお下記のように、scriptタグの中に入れても問題ありません(むしろそうしたい!)。
<main class="py-4">
@yield('content')
</main>
</div>
<script>
@yield('js') <-- ここに追加
</script>
</body>
</html>
ただその場合、vueを記述する側のhome.blade.phpで補完やハイライト等エディタの恩恵が受けられなくなってしまいます。
したがって継承元のlayouts.appではscriptタグには入れていません。
2. resource/views/home.blade.phpにscriptを追加する
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Vueお試し</div>
<div class="card-body">
<input v-model="name">
<p>名前: @{{ name }}</p>
</div>
</div>
</div>
</div>
</div>
@endsection
@section('js')
<script>
const app = new Vue({
el: '#app',
data: () => {
return {
name: '',
}
},
methods: {}
});
</script>
@endsection
inputに入力されたものをpタグに表示する、v-modelを使用したシンプルなものを用意しました。
ただこのままではうまく行きません。
home:66 Uncaught ReferenceError: Vue is not defined
at home:66:17
app.js:33420 [Vue warn]: Property or method "name" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
(found in <Root>)
これは既にapp.jsでVueインスタンスが作成されていることに起因しています。
次はこの問題を解消しましょう🤔
3.個々のblade.phpでそれぞれのVueインスタンスを作成する
まずapp.jsを修正します。
require('./bootstrap');
window.Vue = require('vue').default;
次にapp.blade.phpでapp.jsを読み込んでいる部分のdeferを削除します。
// デフォルトで13行目
<script src="{{ asset('js/app.js') }}"></script>
deferの役割についてはココ!からご確認ください☕️
最後に、プロジェクトルートでnpm run dev
を入力してください。
これでhome.blade.phpにvueが記述できるようになったことが確認できます。
他のblade.phpについても、layouts.appを継承していれば、同様の方法でVueを記述することができます👍
end.Githubのリポジトリ
今回作成したコードは以下のリポジトリに載せてあります。