4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Laravel】 blade.phpファイルの中でvueを書く

Last updated at Posted at 2022-12-25

環境

  • 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と入力するだけで検証結果が確認できるようになります。

web.php
Route::get('/', function () {
    return view('welcome');
});

// Auth::routes(); <- コメントアウト
 
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
HomeController
    public function __construct()
    {
        // $this->middleware('auth'); <- コメントアウト
    }

1.resource/views/layouts/app.blade.phpにyieldを追加する

そこでhome.blade.phpを見てみると、layouts.appを継承していることがわかるので、継承元のlayouts.appにscriptを記述するためのyieldを追加します。

app.blade.php
<!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を追加する

home.blade.php
@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を修正します。

app.js
require('./bootstrap');

window.Vue = require('vue').default;

次にapp.blade.phpでapp.jsを読み込んでいる部分のdeferを削除します。

app.blade.php
// デフォルトで13行目
<script src="{{ asset('js/app.js') }}"></script>

deferの役割についてはココ!からご確認ください☕️

最後に、プロジェクトルートでnpm run devを入力してください。
これでhome.blade.phpにvueが記述できるようになったことが確認できます。
他のblade.phpについても、layouts.appを継承していれば、同様の方法でVueを記述することができます👍

end.Githubのリポジトリ

今回作成したコードは以下のリポジトリに載せてあります。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?