【Larave8】InertiaでVue2系を使う方法

Laravel
はむ
はむ

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

 

vue-loaderはVueコンポーネントをJavaScript モジュールに変換するwebpackのローダーです。このおかげで、VueがJavaScriptに変換されて使用できます。

 

 

パッケージのインストール

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タグで囲う必要があります。

 

マルチルートノードとは簡単に言うと「大本となるタグ(ノード)が複数ある状態」です。以下のコードは大本となるタグがparent1のdivとparent2のdivの2つあります。
<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を使って色々なライブラリを試してみましょう!!

コメント

タイトルとURLをコピーしました