Laravelでは、デフォルトでVue.jsをサポートしており、バンドルツールのWebpackも簡単に使えます。ただ、流石にいい感じのUIコンポーネントを自前で1から作るのは大変なので、Vue.jsのフレームワークとして有名な Vuetify を採用してみることにしました。
Vuetifyのドキュメントを参考にしながらインストールや設定を行ったのですが、結構苦労したので、備忘録として残しておくことにします。Laravel, Vue.js, Laravel-Mix, Vuetify のバージョンはそれぞれ以下の通りです。
- Laravel: 5.8.31
- Vue.js: 2.6.10
- Laravel-Mix: 4.1.2
- Webpack: 4.39.1
- Vuetify: 2.0.5
Vuetifyのインストールの流れ
Laravelには、デフォルトではVuetifyは入っていないので、パッケージのインストールと設定が必要です。また、今回はLaravel-Mixでコンパイルもしてもらいたいので、Vuetify-LoaderをインストールとWebpackの設定も必要です。
手順の概要は以下の通りです。
- VuetifyとVuetify-Loaderをインストール
webpack.mix.js
にVuetify-Loaderをプラグインとして設定- Vuetifyの設定ファイルを作成して
app.js
のVueインスタンスに追加
VuetifyとVuetify-Loaderのインストール
Laravelのプロジェクトディレクトリ配下で npm
や yarn
を使ってインストールします。今回はLaravel-MixでVuetifyのコンポーネントもコンパイルしたいので、CDNは用いないことを想定しています。
npm install vuetify -S npm install vuetify-loader -D
Vuetify はアイコンにアイコンフォントを利用するので、インストールします。
npm install @mdi/font -D
Webpackの設定
VuetifyとVuetify-Loaderをインストールしたら、Webpackの設定をします。Laravel-MixでのWebpackの設定は、 webpack.mix.js
に記述します。Webpackの設定は、Laravel-Mixの webpackConfig
メソッドを用います。 webpackConfig
メソッドの引数には、Webpackの設定で module.export
するオブジェクトと同様のものを指定するようです。
Vuetify-Loaderを読みこませるために、 'vuetify-loader/lib/plugin
を読み込み、Vuetify-Loaderのインスタンスを plugins
プロパティに設定します。 webpack.mix.js
の中身は以下の通りです。
const mix = require('laravel-mix'); const VuetifyLoaderPlugin = require('vuetify-loader/lib/plugin'); mix.webpackConfig({ plugins: [ new VuetifyLoaderPlugin(), ], }); mix.js('resources/js/app.js', 'public/js') .sass('resources/sass/app.scss', 'public/css');
Vuetifyの設定
公式ドキュメントでは、 src/plugins/vuetify.js
に、VuetifyをVue.jsのプラグインとして読み込ませる方法が書いてありますが、Laravelのディレクトリ構造と異なるので、 resources/js/plugins/vuetify.js
に記述することとします。設定ファイルの場所が違うこと以外は、基本的には公式ドキュメントと同様に設定します。
まず、設定ファイルを、公式ドキュメントと同様に resources/js/plugins/vuetify.js
に記述します。アイコンフォントの設定もここで行います。アイコンフォントのモジュールを読み込み、Vuetifyインスタンスの引数のオブジェクト内に記述します。
import '@mdi/font/css/materialdesignicons.css'; import Vue from 'vue'; import Vuetify from 'vuetify/lib'; Vue.use(Vuetify); export default new Vuetify({ icons: { iconfont: 'mdi', }, });
Vuetifyをプラグインとして読み込ませるために、 resources/js/app.js
を以下のように編集します。
require('./bootstrap'); window.Vue = require('vue'); import vuetify from './plugins/vuetify'; const app = new Vue({ vuetify, el: '#app', });
これで、Laravel-MixでもVuetifyのコンポーネントが使えるようになります。全てのコンポーネントについて検証したわけではありませんが、明示的にVuetifyのコンポーネントを import
していなくても、問題なく利用できるようになっているはずです。
ハマった点
自分で設定をしている際に、以下の2つの点でハマりました。
Vuetifyのコンポーネントが読み込まれないものがある
最初、Webpackの設定しか書いていませんでした。Webpackの設定自体は通り、試しに v-btn
コンポーネントを利用した際には、問題なく表示されました。 v-card
も同様に使えました。
これで使えるようになったと糠喜びをしていたのも束の間、 v-pagination
を試したら画面上に表示されず、コンソールにエラーが出力されていました。
[Vue warn]: Error in render: TypeError: this.$vuetify is undefined v-pagination
どうやら、Vuetify-Loaderの制約で、 Dynamic Component や Functional Component は手動で読み込まないと使えないようです。 ドキュメントを読んだのですが、どうしても Functional Component がどのようなものかイマイチはっきり分からず、どのコンポーネントが Functional Component に当たるか区別がつかないので、別の手段を模索しました。
Vuetify-Loader で全部読み込みきれなかったようだったので、次は Vuetify の設定ファイルのみ作って、コンパイルしなおしましたが、今度はVuetifyがうまく動かなくなったようでした。結局、Vuetify-LoaderとVuetifyの設定の両方を書いたら、問題なく動くようになりました。
この辺りについて、自分自身で完全に理解しきれていないので、どなたか助言をいただけると、個人的に大変助かります。
VuetifyのデフォルトのCSSが効いていない
結論から書くと、 v-app
の中にVuetifyのコンポーネントを入れ忘れていただけでした。公式ドキュメントにも、Vuetifyのコンポーネントは、 v-app
の中に入れろと書いていましたが、とりあえずVuetifyのコンポーネントが動くか試したかったので、そのことをすっかり忘れていました。とても初歩的なミスでした。
v-app
を書き忘れていることに気づくまで、Vuetifyの設定を色々いじっていました。 v-btn
のデフォルトの背景色はCSS効いてるっぽいけど、フォントが違ったり、 class="primary"
を指定しても背景色が変わらなかったりで、コンポーネントのCSSを明示的に読み込まなければいけないのかと勘違いしていました。
まとめ
LaravelにVuetifyをインストールする場合、Vue CLI 3を利用するのとは少し勝手が違うので、設定に苦戦しました。とりあえず、 Vuetify-LoaderをLaravel-MixのWebpackにプラグインとして読み込ませ、VueインスタンスにVuetifyをプラグインとして読み込ませれば、各SFCでVuetifyのコンポーネントの import
を書かなくても、自動で読み込まれるようになりました。
自分自身、挙動を完璧に理解しきれていないので、もし詳しい方がいらっしゃれば、ご教授願えればと思います。