
Laravel・Vue・Inertiaの組み合わせでアプリを作り始めたのですが、Vue3系で使えるライブラリが少なくて困っています。どうすればいいでしょうか?

Inertiaを使うとVue3系がデフォルトになるため、使えるライブラリが限られてしまいます。Vueを3系から2系に落としてアプリを作っていきましょう!
今回は、Laravel・Vue・Inertiaでアプリを作り出したこんな皆さんにおすすめです!
- 使えるライブラリが少なくて困っている
- Inertiaでvuetifyやstripeを使いたい
- 慣れ親しんだvue2系でアプリをつくりたい
Vue3系から2系にする方法を解説します。作業の全体図は次のとおりです!
- InertiaをLaravelに導入する
- npmのパッケージをVue3系から2系に変更し、依存関係を2系に合わせる
- Vue3系の書き方で記述されている箇所を、2系の書き方に修正する
それでは早速始めましょう!
InertiaをLaravelに導入
InertiaをLaravelに導入していない方は、こちらで詳しく解説しています。
npmパッケージの変更
InertiaでVue2系を使うためには、デフォルトで導入されたVue3系のパッケージをアンインストールして、Vue2系に必要なパッケージを導入する必要があります。
まず現在のpackage.jsonを見てみましょう。
「”vue”: “^3.0.5″」とあるようにVue3系がインストールされています。
package.json
{
"private": true,
"scripts": {
"dev": "npm run development",
"development": "mix",
"watch": "mix watch",
"watch-poll": "mix watch -- --watch-options-poll=1000",
"hot": "mix watch --hot",
"prod": "npm run production",
"production": "mix --production"
},
"devDependencies": {
"@inertiajs/inertia": "^0.10.0",
"@inertiajs/inertia-vue3": "^0.5.1",
"@inertiajs/progress": "^0.2.6",
"@tailwindcss/forms": "^0.4.0",
"@vue/compiler-sfc": "^3.0.5",
"autoprefixer": "^10.2.4",
"axios": "^0.21",
"laravel-mix": "^6.0.6",
"lodash": "^4.17.19",
"postcss": "^8.2.13",
"postcss-import": "^14.0.1",
"tailwindcss": "^3.0.0",
"vue": "^3.0.5",
"vue-loader": "^16.1.2"
}
}
パッケージのアンインストール
まず、Vue3系のパッケージや依存関係のあるパッケージをアンインストールします。
npm uninstall --save-dev @inertiajs/inertia @inertiajs/inertia-vue3 npm uninstall --save-dev vue npm uninstall --save-dev @inertiajs/progress npm uninstall --save-dev vue-loader npm uninstall --save-dev @vue/compiler-sfc
パッケージのインストール
Vue2系に必要なパッケージを導入します。
さらに、Vue2系に合うように依存関係を調整しています。
@inertiajs/inertia-vueが2系のパッケージになるため、このあとは2系の依存関係にあうバージョンがインストールされていきます。
npm install --save-dev @inertiajs/inertia @inertiajs/inertia-vue npm install --save-dev vue npm install --save-dev @inertiajs/progress npm install --save-dev vue-loader npm install --save-dev vue-template-compiler npm install --save-dev portal-vue
もう一度package.jsonを見てみましょう。
「”vue”: “^2.6.14″」からVue2系が導入されているのがわかります。vue-loaderのバージョンも2系に合うように依存関係が調整されています。
package.json
{
"private": true,
"scripts": {
"dev": "npm run development",
"development": "mix",
"watch": "mix watch",
"watch-poll": "mix watch -- --watch-options-poll=1000",
"hot": "mix watch --hot",
"prod": "npm run production",
"production": "mix --production"
},
"devDependencies": {
"@inertiajs/inertia": "^0.10.0",
"@inertiajs/inertia-vue": "^0.7.2",
"@inertiajs/progress": "^0.2.6",
"@tailwindcss/forms": "^0.2.1",
"@vue/compiler-sfc": "^3.0.5",
"autoprefixer": "^10.2.4",
"axios": "^0.21",
"laravel-mix": "^6.0.6",
"lodash": "^4.17.19",
"portal-vue": "^2.1.7",
"postcss": "^8.2.13",
"postcss-import": "^14.0.1",
"tailwindcss": "^2.1.2",
"vue": "^2.6.14",
"vue-loader": "^15.9.8",
"vue-template-compiler": "^2.6.14"
}
}
Vue2系の記述に書き直す
読み込むパッケージを変更
「@inertiajs/inertia-vue3」を読み込んでいた箇所を「@inertiajs/inertia-vue」に変更します。
複数個所存在するため、一括置換してあげましょう!
例)resources/js/Pages/Auth/Register.vue
【変更前】
import {Head, Link} from '@inertiajs/inertia-vue';import {Head, Link} from '@inertiajs/inertia-vue3';
【変更後】
import {Head, Link} from '@inertiajs/inertia-vue';import {Head, Link} from '@inertiajs/inertia-vue';
app.jsを変更
app.jsをVue2系用に変更します。
resources/js/app.jsresources/js/app.js
require('./bootstrap');
// Import modules...
import Vue from 'vue';
import { App as InertiaApp, plugin as InertiaPlugin } from '@inertiajs/inertia-vue';
import PortalVue from 'portal-vue';
Vue.mixin({ methods: { route } });
Vue.use(InertiaPlugin);
Vue.use(PortalVue);
const app = document.getElementById('app');
new Vue({
render: (h) =>
h(InertiaApp, {
props: {
initialPage: JSON.parse(app.dataset.page),
resolveComponent: (name) => require(`./Pages/${name}`).default,
},
}),
}).$mount(app);
template直下にdivを追加
Vue2系ではマルチルートノードコンポーネントがサポートされていないため。必ずdivタグで囲う必要があります。
<div class="parent1">
<p>親はparent1</p>
</div>
<div class="parent2">
<p>親はparent2</p>
</div>
template直下にdivタグを追加してルートノードを一つにします。
例)resources/js/Pages/Dashboard.vue
<template> <div> <Head title="Dashboard"/> <BreezeAuthenticatedLayout> <template #header> <h2 class="font-semibold text-xl text-gray-800 leading-tight"> Dashboard </h2> </template> <div class="py-12"> <div class="max-w-7xl mx-auto sm:px-6 lg:px-8"> <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg"> <div class="p-6 bg-white border-b border-gray-200"> You're logged in! </div> </div> </div> </div> </BreezeAuthenticatedLayout> </div> </template>
このdivタグの追加を以下のコンポーネントで行います。
- Register
- Welcome
- VerifyEmail
- Dashboard
- ResetPassword
- Login
- ForgotPassword
- ConfirmPassword
Dropdown.vueを書き直す
なぜかわかりませんが、Dropdown.vueだけsetupを利用したcompositionAPIで記述されているので、optionsAPIに書き直します。
resources/js/Components/Dropdown.vue
export default {
data() {
return {
open: false,
}
},
props: {
align: {
default: 'right'
},
width: {
default: '48'
},
contentClasses: {
default: () => ['py-1', 'bg-white']
}
},
methods: {
closeOnEscape(e) {
if (this.open && e.key === 'Escape') {
this.open = false
}
}
},
mounted() {
document.addEventListener('keydown', closeOnEscape)
},
destroyed() {
document.removeEventListener('keydown', closeOnEscape)
},
computed: {
widthClass() {
return {
'48': 'w-48',
}[this.width.toString()]
},
alignmentClasses() {
if (this.align === 'left') {
return 'origin-top-left left-0'
} else if (this.align === 'right') {
return 'origin-top-right right-0'
} else {
return 'origin-top'
}
},
}
}
</script>
双方向バインディングを書き直す
双方向バインディングの仕組みがVue2系と3系で大きく異なるので書き直します。これをしないと入力した値が反映されません。
3系では、v-modelを利用して双方向バインディングを実現していますが、2系ではsyncを利用して実現します。
例)resources/js/Pages/Auth/Login.vue
【変更前】
<BreezeInput id="email" type="email" class="mt-1 block w-full" v-model="form.email" required autofocus autocomplete="username"/>
【変更後】
<BreezeInput id="email" type="email" class="mt-1 block w-full" :modelValue.sync="form.email" required autofocus autocomplete="username"/>
同様の修正を以下のコンポーネントの各入力フォームで行います。
- Register.vue
- Login.vue
- ResetPassword.vue
- ForgotPassword.vue
以上で修正は完了です!ビルドしてみましょう!!
npm run dev
画面が表示されて、ユーザー登録してダッシュボードが表示されたら成功です。お疲れさまでした!


途中で心が折れそうになりましたが、なんとかたどり着きました。ありがとうございます!これでライブラリを使ってアプリケーションを作れます!

vue3系対応のライブラリはまだまだ少ないので、2系で書くことは多いですよね!今度はInertiaを使って色々なライブラリを試してみましょう!!



コメント