【Laravel11】 基本bladeで、Vueコンポーネントを一部入れたい

はじめに

このUIでバニラjsで作るのしんどいからVueコンポーネント使いたい…。けど全体的にbladeで作ってきてるし、このプロジェクトでVueに精通してる人は少ないからSPAにするのは厳しいな…

ということで基本はbladeで、一部Vueのコンポーネントを入れるようにしました。

↓こんな感じで使えるように

例:子blade.php(app.blade.phpのslotに入るところ)
<x-app-layout>
    <div>
        ...
        <file-uploader></file-uploader> <!-- Vueコンポーネント-->

Vueをマウントする場所を決める

まずVueコンポーネントを使う範囲を考えて、マウントする場所を決めましょう。その親要素にidを振ります。
ほんとは範囲狭い方が良いんだと思います。

app.blade.php
<head>
    ...
    @vite(['resources/js/app.js']) <!-- app.jsを読み込んでおきましょう! -->
</head>
<body>
    <div id="vue-p"><!-- この配下で使えるようにするぜ!-->
        <main class="flex-fill bg-light" style="width:80%;">
            {{ $slot }}
        </main>
    </div>
</body>

app.js

コンポーネントだけを登録してマウントしちゃいましょう

app.js
import { createApp } from 'vue';
const app = createApp({}); //ルートコンポーネントは空に!

//コンポーネントを登録
import FileUploader from './components/FileUploader.vue';
app.component('file-uploader', FileUploader);

import Modal from './components/Modal/Modal.vue';
app.component('modal', Modal);

...

app.mount('#vue-p') //さっきのマウントする場所のID

ルートコンポーネントを空にすると、マウント対象のinnerHTML がテンプレートになります。つまり元の

HTML
<div id="vue-p"> ... </div>

の中身がそのまま表示されます。

npm run dev (or build) と リロードをして確認してみましょう

ただし注意点があります!!

大事な注意点

<div id=vue-p> ... </div> の中身は、Vueのテンプレートとして使われるので、<script></script>は効きません!その他動的なものとか使えないかも。

回避策

名前付きスコープでvueのマウントの外に出してあげる

子blade.php
<x-app-layout>
    <file-uploader></file-uploader>

    <x-slot:javascript> <!-- 名前付きスコープ -->
        <script>....</script>
    </x-slot>
</x-app-layout>

app.blade.php
<body class="font-sans antialiased">
    <div id="vue-p">
        <main class="flex-fill bg-light" style="width:80%;">
            {{ $slot }}
        </main>
    </div>

    <!-- 外ならOK -->
    {{ $javascript ?? '' }}
</x-slot>

なんにせよ狭い方が良いですね!
最近はVue使うならSPAか、Inertiaとからしいので、こういう方法は導入時とか訳アリの時だけの方が良いのかな…?と思っています。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール