Laravelの8系でモダンフロントを導入したいんですけど、どうすれば実現できるかわかりません
Laravel8系は、Inertiaが導入されて簡単にモダンフロントが扱えるようになりました。今回は実際にInertia + Vueを導入してみましょう!
今回は「Inertia.js」について、次の3点を説明します。バックエンドはLaravelでフロントエンドはVueで作成したいと考えている人は簡単に実現することができます。
- Inertia.jsとは何か
- 実際にLaravelに導入する
- Vue3から登場したcompositionAPIに書き換える
Inertia.jsとは何か
Inertia.jsは「これまでのLaravelと同じ感覚でVueやReactなどのモダンフロントを使用することができる仕組み」です。
「フロントエンドとバックエンドは分離されているけど、一緒に使えたら楽だよね」を実現したものです。
フロントエンドとバックエンドの分離
Laravelとモダンフロントでシングルページアプリケーション(SPA)を作ろうとした時、フロントエンドとバックエンドを分離していました。
それぞれが独立してデプロイされて存在し、フロントエンドからバックエンドのAPIを叩きに行っていました。
アプリケーションが独立しているため、以下のメリットがありました。
- 機能ごとに使用言語が分けられるため、技術選定が柔軟にできる
- エラーが発生しても原因を特定しやすい
- 開発をフロントエンドとバックエンドで分離できる
このように、アプリケーションの役割が分離されているものを「疎結合」と言います。
一方で、小・中規模開発をするときは、アプリ間の結びつきを強めてしまった方が、アプリを素早く作れます。
その代わり、結びつきが強いため、エラー発生時に原因を特定しにくかったり、言語が固定されて変更しにくいなどのデメリットも発生します。
このようにアプリケーションの役割の結びつきが強いものを「密結合」と言います。
疎結合と密結合はどちらが優れているというわけではなく、自分の置かれている状況に合わせて使い分ける必要があります。
時代の流れとして、RailsやLaraveの密結合全盛の時代からアプリの大規模化によって疎結合がもてはやされました。
その結果疎結合のデメリットがわかり、また、密結合の良さが見直されてきたという印象です。
Laravelとモダンフロントの結びつきを強める
フロントエンドからバックエンドのAPIを叩きに行かず、これまでLaravelを利用していた時の感覚でSPAを作る橋渡しをするのがInertia.jsです。
具体的には、ControllerからデータをVueファイルに直接渡せたり、リンクをクリックしたときにページ全体を読み込むレンダリングは行われず、JavaScriptによるHTTP通信であるXMLHttpRequest で行われます。
シンプルにLaravelのview部分をモダンフロントに置き換えた感じです。ルーティングもLarave側で行うため、Vue RouterやReact Routerは使う必要がありません。かなり便利です!
先ほどの話で言えば、「密結合」になりますね。
それでは具体的な使い方を見ていきましょう!
Inertia.jsを導入する
Laravelのアプリケーションを作り終えたところからスタートです!
アプリケーションのディレクトリでマイグレーションを実行
php artisan migrate
Composerを使用してLaravel Breezeを導入
composer require laravel/breeze --dev
Inertia(vueを利用)を導入
php artisan breeze:install vue
パッケージをインストールしてビルドする
npm install && npm run dev
ローカルにアクセスして、右上にLog inとRegisterが登録されていれば成功です。
ちなみにGitを利用している方は、ビルドに伴い発生する
- /public/css
- /public/js
をgitignoreに追加しておくと便利です。
compositionAPIに書き換える
初期設定されているVueはOptionsAPIで記述されているため、ここでは、ユーザー登録画面とログイン画面をCompositionAPIに書き換えていきます。
ユーザー登録画面
resources/js/Pages/Auth/Register.vue
export default {
layout: BreezeGuestLayout,
components: {
BreezeButton,
BreezeInput,
BreezeLabel,
BreezeValidationErrors,
Head,
Link,
},
data() {
return {
form: this.$inertia.form({
name: '',
email: '',
password: '',
password_confirmation: '',
terms: false,
})
}
},
methods: {
submit() {
this.form.post(this.route('register'), {
onFinish: () => this.form.reset('password', 'password_confirmation'),
})
}
}
}
</script>
を書き換えていきます。
まずは結論
import {Head, Link, useForm} from '@inertiajs/inertia-vue3';
export default {
layout: BreezeGuestLayout,
components: {
BreezeButton,
BreezeInput,
BreezeLabel,
BreezeValidationErrors,
Head,
Link,
},
setup() {
let form = useForm({
name: '',
email: '',
password: '',
password_confirmation: '',
terms: false,
})
const submit = () => {
form.post('register', {
onFinish: () => form.reset('password', 'password_confirmation')
})
}
return {
form,
submit,
}
},
}
</script>
フォーム送信するときは、inertiaが用意しているuseFormをimportします。
import {Head, Link, useForm} from '@inertiajs/inertia-vue3';
dataで記述していたformのstateはuseForm内に記述します。
let form = useForm({
name: '',
email: '',
password: '',
password_confirmation: '',
terms: false,
})
form.postでpost送信できます。第一引数に送信先、第二引数にオプションを設定します。今回は「onFinish」が設定されています。
これは送信後に発動するオプションで、パスワードとパスワードの確認フォームをリセットしています。
ユーザー登録して以下の画面にリダイレクトされれば成功です。
他にもform.getで値を取得したり、送信が成功したときに発動するonSuccessオプションや失敗したときに発動するonErrorオプションなどがあります。
<BreezeButton class="ml-4" :class="{ 'opacity-25': form.processing }"
:disabled="form.processing">
Register
</BreezeButton
form.processingはform送信中に発動します。ここでは透明度を上げて、ボタンを押せなくすることでダブル送信を防止しています。
ログイン画面
修正内容は同じなので、コードだけ載せておきます。
resources/js/Pages/Auth/Login.vue
import {Head, Link, useForm} from '@inertiajs/inertia-vue3';
export default {
layout: BreezeGuestLayout,
components: {
BreezeButton,
BreezeCheckbox,
BreezeInput,
BreezeLabel,
BreezeValidationErrors,
Head,
Link,
},
props: {
canResetPassword: Boolean,
status: String,
},
setup() {
let form = useForm({
email: '',
password: '',
remember: false
})
const submit = () => {
form.post(route('login'), {
onFinish: () => form.reset('password'),
})
}
return {
form,
submit,
}
},
}
</script>
私も簡単に導入できました!CompositionAPIへの書き換え方がわからなかったので助かりました。
Inertiaにはもっと多くの使い方があるので、今後詳しくみていきましょう!
コメント