LoginSignup
5

More than 5 years have passed since last update.

今更だけどLaravel+Vue.jsを試す

Posted at

Webサイトをよりアプリっぽくするために
Vue.jsを試してみます。

開発環境

使用ツール名 バージョン
Laravel 5.7.14
Vue.js 2.5.17
Homestead 6.6.0

やること

  • CDN版で試す
  • NPMで試す
  • 単一ファイルコンポーネント

とりあえず10分くらいで試したい場合

Vue.js公式が優しいので参考にしながら。
CDNから引っ張ってきてやるのが簡単です。

HelloWorld

hello.blade.php
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <p>@{{ message }}</p>
    </div>
    <script>
    new Vue({
        el: '#app',
        data: {
        message: 'Hello Vue.js!'
        }
    });
    </script>
</body>
</html>

blade使っている場合、二重中括弧の前に@付けないと正常に表示されません。

ルーティング

公式のサンプルを先程のHelloWorldに合体させます

hello.blade.php
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
    <div id="app">
        <p>@{{ message }}</p>
        <router-link to="/foo">Go to Foo</router-link>
        <router-link to="/bar">Go to Bar</router-link>

        <router-view></router-view>
    </div>
    <script>
    const Foo = { template: '<div>foo</div>' };
    const Bar = { template: '<div>bar</div>' };

    const routes = [
        { path: '/foo', component: Foo },
        { path: '/bar', component: Bar }
    ];

    const router = new VueRouter({
        routes // `routes: routes` の短縮表記
    });


    new Vue({
        el: '#app',
        data: {
            message: 'Hello Vue.js!'
        },
        router: router
    });
    </script>
</body>
</html>

ただこれだとFooやBarのテンプレートの中に全てのHTMLを書かねばなりません。
ページ内の1コンポーネントならいいですがページ全体となると気が遠くなりますね。
そこで単一ファイルコンポーネントに行き着くのですが、この辺りからCDN版ではできなくなります。はやー

もう少し突っ込んで試したい場合

NPMインストール

Laravelだとこの辺り最初から揃っているのが嬉しいです(注:揃っているがインストールはされていない)
Laravelのインストールディレクトリ直下にpackage.jsonがあるのですが、何もいじらず以下のコマンドを入力します

console
$ vagrant ssh
$ npm install

後々、と言ってもすぐに必要になるのでvue-routerもインストールしてしまいます。

console
$ npm install vue-router

この後コンパイルすると、必要なファイル一式がどこどこ出来上がってきます。
Laravelの場合Laravel Mixというコンポーネントを使ってVue.jsと連携してくれます。

console
$ npm run dev

これで準備完了です。

NPM版に合わせてソース修正

既に単一ファイルコンポーネントが入ってしまってますが、こんな感じで。

hello.blade.php
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <link rel="stylesheet" href="{{ mix('css/app.css') }}">
</head>
<body>
    <div id="app">
        <p>@{{ message }}</p>
        <router-link to="/foo">Go to Foo</router-link>
        <router-link to="/bar">Go to Bar</router-link>

        <router-view></router-view>
    </div>
    <script src="{{ mix('js/app.js') }}" ></script>
</body>
</html>

vueのソースを書いていた部分がjs/app.jsに移動しています。

js/app.js
import VueRouter from 'vue-router';

import page1 from './components/page1.vue';
import page2 from './components/page2.vue';

require('./bootstrap');

window.Vue = require('vue');

const routes = [
    { path: '/page1', component: page1 },
    { path: '/page2', component: page2 }
];

const router = new VueRouter({
    routes // `routes: routes` の短縮表記
});

const app = new Vue({
    el: '#app',
    data: {
        message: 'Hello Vue.js!'
    },
    router: router
});
js/components/page1.vue
<template>
    <div>foo</div>
</template>

<script>
</script>

<style>
</style>

page2.vueは同じソースなので省略します。

ここまで出来たらビルドして動作を確認します。

console
$ npm run dev

エラー類

- Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.

npm run devあたりで表示されるエラー
templateタグの中はdivで括らないと上記エラーが出ます。

画面遷移でずれる

absoluteで位置決めしておかないと画面遷移でパーツがいろいろずれます

その他メモ

全ページ共通のcssを読み込む

js/app.js
require('../../public/css/laravel-vue.css');

こんな感じで。
ブラウザ側から見えるパスではなく、サーバー内のパスで書いています。

bladeの範囲

.vueの単一ファイルコンポーネントの中はbladeの範囲外となります。

つづく

参考

https://jp.vuejs.org/
https://router.vuejs.org/ja/
https://blog.capilano-fw.com/?p=432
http://blog.asial.co.jp/1496
https://techblog.securesky-tech.com/entry/2018/09/03/

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
5