Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

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

開発環境

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

やること

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

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

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

https://jp.vuejs.org/v2/guide/index.html

HelloWorld

https://jsfiddle.net/chrisvfritz/50wL7mdz/

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/

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away