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を使って色々なライブラリを試してみましょう!!
コメント