📚

Laravel 8でInertia+Vuetifyを使ってみる - Laravel JetStream - アタック

2021/10/03に公開

はじめに

経緯

Laravel 6で組んでいるAPIサーバーをLaravel 8で組みなおしてみるという一連の実証です。
以前の、Laravel 8のAPI認証を味見するのとおり、APIサーバーとしてSanctumのAPI認証を試してみました。

この仕組みは、Vuetifyを利用したSPAとの連携を想定した仕組みです。
(ちなみに、SPA認証を利用しないのは、SPA以外からも連携する想定があるから、です。)

そんな折、こちらの方の記事が目に留まりました。(感謝)

Laravel JetStreamのinertiaで、Vuetifyが使えるですって?!

ということで、試します。

Laravel JetStreamについて

公式のドキュメントLaravel Jetstream 1.0が用意されています。

ログイン、ユーザー登録、メール確認、2要素認証、セッション管理などなど、大体のWEBアプリケーションで必要となる仕組みのパッケージ的なものです。
Laravel 6では、

composer require laravel/ui:^1.0

からの、

php artisan ui vue --auth

などとすることで、同等のことが行えました。(vueの箇所はタイプで、bootstrap, vue, react の3タイプを指定可能)

このあたりの仕組みがJetStreamに置き換えられているとのことです。

環境

環境は、こちらの記事と同等のものを利用するべく、(2) Laravelのプロジェクト作成 以降を実施して新しい環境を作成します。

環境構築手順:基本

プロジェクト作成

※詳細は、こちらの記事を参照

  1. create project

    laradock@9760cc7de2d2:/var/www# composer create-project laravel/laravel example-app02 "8.*"
    
    laradock@9760cc7de2d2:/var/www$ vi example-app02/.env
    
    APP_URL=http://localhost
    ↓
    APP_URL=http://localhost/app02
    ASSET_URL=/app02
    

    ※その他も調整
    ※必要に応じてexample-app02用のデータベースも新規作成(ここではdefaultデータベースをmigrate:refreshして利用する想定)

  2. Laravelプロジェクト公開ディレクトリの準備

    laradock@9760cc7de2d2:/var/www# cd public/
    laradock@9760cc7de2d2:/var/www/public# ln -s ../example-app02/public/ app02
    
  3. nginxのdefault.conf設定ファイルの修正

    /var/www/laradock/nginx/sites/default.conf
        location /app02/ {
    	try_files $uri $uri/ /app02/index.php$is_args$args;
        }
    

    Dockerホスト側でnginxを再起動

    laradock> docker-compose restart nginx
    Restarting laradock_nginx_1 ... done
    

この時点で、http://localhost/app02/にブラウザアクセスするとLaravelのWelcome画面が表示される。

Laravel JetStreamをインストール

  1. プロジェクトフォルダに移動し、Composerでlaravel/jetstreamを追加

    laradock@9760cc7de2d2:/var/www$ cd example-app02
    laradock@9760cc7de2d2:/var/www/example-app02$ composer require laravel/jetstream
    
    実行イメージ
    Using version ^2.4 for laravel/jetstream
    ./composer.json has been updated
    Running composer update laravel/jetstream
    Loading composer repositories with package information
    Updating dependencies
    Lock file operations: 9 installs, 0 updates, 0 removals
      - Locking bacon/bacon-qr-code (2.0.4)
      - Locking dasprid/enum (1.0.3)
      - Locking jaybizzle/crawler-detect (v1.2.106)
      - Locking jenssegers/agent (v2.6.4)
      - Locking laravel/fortify (v1.8.2)
      - Locking laravel/jetstream (v2.4.1)
      - Locking mobiledetect/mobiledetectlib (2.8.37)
      - Locking paragonie/constant_time_encoding (v2.4.0)
      - Locking pragmarx/google2fa (8.0.0)
    Writing lock file
    Installing dependencies from lock file (including require-dev)
    Package operations: 9 installs, 0 updates, 0 removals
      - Downloading dasprid/enum (1.0.3)
      - Downloading bacon/bacon-qr-code (2.0.4)
      - Downloading jaybizzle/crawler-detect (v1.2.106)
      - Downloading paragonie/constant_time_encoding (v2.4.0)
      - Downloading pragmarx/google2fa (8.0.0)
      - Downloading laravel/fortify (v1.8.2)
      - Downloading mobiledetect/mobiledetectlib (2.8.37)
      - Downloading jenssegers/agent (v2.6.4)
      - Downloading laravel/jetstream (v2.4.1)
      - Installing dasprid/enum (1.0.3): Extracting archive
      - Installing bacon/bacon-qr-code (2.0.4): Extracting archive
      - Installing jaybizzle/crawler-detect (v1.2.106): Extracting archive
      - Installing paragonie/constant_time_encoding (v2.4.0): Extracting archive
      - Installing pragmarx/google2fa (8.0.0): Extracting archive
      - Installing laravel/fortify (v1.8.2): Extracting archive
      - Installing mobiledetect/mobiledetectlib (2.8.37): Extracting archive
      - Installing jenssegers/agent (v2.6.4): Extracting archive
      - Installing laravel/jetstream (v2.4.1): Extracting archive
    1 package suggestions were added by new dependencies, use `composer suggest` to see details.
    Generating optimized autoload files
    > Illuminate\Foundation\ComposerScripts::postAutoloadDump
    > @php artisan package:discover --ansi
    Discovered Package: facade/ignition
    Discovered Package: fruitcake/laravel-cors
    Discovered Package: jenssegers/agent
    Discovered Package: laravel/fortify
    Discovered Package: laravel/jetstream
    Discovered Package: laravel/sail
    Discovered Package: laravel/sanctum
    Discovered Package: laravel/tinker
    Discovered Package: nesbot/carbon
    Discovered Package: nunomaduro/collision
    Package manifest generated successfully.
    78 packages you are using are looking for funding.
    Use the `composer fund` command to find out more!
    > @php artisan vendor:publish --tag=laravel-assets --ansi
    No publishable resources for tag [laravel-assets].
    Publishing complete.
    

    Vue 2を適用するため、composer.jsonでバージョンを調整しアップデート(ダウングレード)

    composer.json
    "laravel/jetstream": "^2.4","laravel/jetstream": "2.1.4",
    

    ^2.1.4のように^をつけるとダウングレードできないようなので注意

    laradock@9760cc7de2d2:/var/www/example-app02$ composer update
    
    実行イメージ
    Loading composer repositories with package information
    Updating dependencies
    Lock file operations: 0 installs, 2 updates, 4 removals
      - Removing dflydev/dot-access-data (v3.0.1)
      - Removing league/config (v1.1.1)
      - Removing nette/schema (v1.2.1)
      - Removing nette/utils (v3.2.5)
      - Downgrading laravel/jetstream (v2.4.2 => v2.1.4)
      - Downgrading league/commonmark (2.0.2 => 1.6.6)
    Writing lock file
    Installing dependencies from lock file (including require-dev)
    Package operations: 0 installs, 2 updates, 4 removals
      - Removing nette/utils (v3.2.5)
      - Removing nette/schema (v1.2.1)
      - Removing league/config (v1.1.1)
      - Removing dflydev/dot-access-data (v3.0.1)
      - Downgrading league/commonmark (2.0.2 => 1.6.6): Extracting archive
      - Downgrading laravel/jetstream (v2.4.2 => v2.1.4): Extracting archive
    Generating optimized autoload files
    > Illuminate\Foundation\ComposerScripts::postAutoloadDump
    > @php artisan package:discover --ansi
    Discovered Package: facade/ignition
    Discovered Package: fruitcake/laravel-cors
    Discovered Package: jenssegers/agent
    Discovered Package: laravel/fortify
    Discovered Package: laravel/jetstream
    Discovered Package: laravel/sail
    Discovered Package: laravel/sanctum
    Discovered Package: laravel/tinker
    Discovered Package: nesbot/carbon
    Discovered Package: nunomaduro/collision
    Package manifest generated successfully.
    77 packages you are using are looking for funding.
    Use the `composer fund` command to find out more!
    > @php artisan vendor:publish --tag=laravel-assets --ansi
    No publishable resources for tag [laravel-assets].
    Publishing complete.
    
  2. Inertiaと同時にJetstreamをインストール
    Inertiaを指定してインストール ※チーム機能を含める(お好みで)

    laradock@9760cc7de2d2:/var/www/example-app02$ php artisan jetstream:install inertia --teams
    
    実行イメージ
    laradock@9760cc7de2d2:/var/www/example-app02$ php artisan jetstream:install inertia --teams
    Migration created successfully!
    ./composer.json has been updated
    Running composer update inertiajs/inertia-laravel laravel/sanctum tightenco/ziggy
    Loading composer repositories with package information
    Updating dependencies
    Lock file operations: 2 installs, 0 updates, 0 removals
      - Locking inertiajs/inertia-laravel (v0.3.6)
      - Locking tightenco/ziggy (v1.4.1)
    Writing lock file
    Installing dependencies from lock file (including require-dev)
    Package operations: 2 installs, 0 updates, 0 removals
      - Downloading inertiajs/inertia-laravel (v0.3.6)
     0/1 [>---------------------------]   0%
     1/1 [============================] 100%
      - Installing inertiajs/inertia-laravel (v0.3.6): Extracting archive
      - Installing tightenco/ziggy (v1.4.1): Extracting archive
     0/2 [>---------------------------]   0%
     2/2 [============================] 100%
    Generating optimized autoload files
    > Illuminate\Foundation\ComposerScripts::postAutoloadDump
    > @php artisan package:discover --ansi
    Discovered Package: facade/ignition
    Discovered Package: fruitcake/laravel-cors
    Discovered Package: inertiajs/inertia-laravel
    Discovered Package: jenssegers/agent
    Discovered Package: laravel/fortify
    Discovered Package: laravel/jetstream
    Discovered Package: laravel/sail
    Discovered Package: laravel/sanctum
    Discovered Package: laravel/tinker
    Discovered Package: nesbot/carbon
    Discovered Package: nunomaduro/collision
    Discovered Package: tightenco/ziggy
    Package manifest generated successfully.
    78 packages you are using are looking for funding.
    Use the `composer fund` command to find out more!
    > @php artisan vendor:publish --tag=laravel-assets --ansi
    No publishable resources for tag [laravel-assets].
    Publishing complete.
    Copied Directory [/vendor/laravel/sanctum/database/migrations] To [/database/migrations]
    Copied File [/vendor/laravel/sanctum/config/sanctum.php] To [/config/sanctum.php]
    Publishing complete.
    Middleware created successfully.
    
    Inertia scaffolding installed successfully.
    Please execute "npm install && npm run dev" to build your assets.
    
  3. インストールを完了する
    パッケージをインストール

    laradock@9760cc7de2d2:/var/www/example-app02$ npm install
    
    実行イメージ
    npm WARN deprecated querystring@0.2.0: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
    npm WARN deprecated uuid@3.4.0: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
    
    added 835 packages, and audited 836 packages in 26s
    
    92 packages are looking for funding
      run `npm fund` for details
    
    found 0 vulnerabilities
    
    参考 作業後のpackage.json
    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.8.2",
    	"@inertiajs/inertia-vue": "^0.5.4",
    	"@tailwindcss/forms": "^0.2.1",
    	"@tailwindcss/typography": "^0.3.0",
    	"autoprefixer": "^10.0.2",
    	"axios": "^0.21",
    	"laravel-mix": "^6.0.6",
    	"lodash": "^4.17.19",
    	"portal-vue": "^2.1.7",
    	"postcss": "^8.1.14",
    	"postcss-import": "^12.0.1",
    	"tailwindcss": "^2.0.1",
    	"vue": "^2.5.17",
    	"vue-loader": "^15.9.6",
    	"vue-template-compiler": "^2.6.10"
        }
    }
    

    ビルド

    laradock@9760cc7de2d2:/var/www/example-app02$ npm run dev
    
    実行イメージ
    ✔ Mix
      Compiled successfully in 7.22s
    
    
       Laravel Mix v6.0.31
    
    
    ✔ Compiled Successfully in 7068ms
    ┌──────────────────────────────────────┬──────────┐
    │                                 File │ Size     │
    ├──────────────────────────────────────┼──────────┤
    │                           /js/app.js │ 2.2 MiB  │
    │                          css/app.css │ 42.7 KiB │
    └──────────────────────────────────────┴──────────┘
    webpack compiled successfully
    
  4. マイグレーション

    laradock@9760cc7de2d2:/var/www/example-app02$ php artisan migrate
    

    ※必要に応じて migrate:resetの実行や、migrate:freshで実行

Inertiaのセットアップ

初期設定を実施

laradock@9760cc7de2d2:/var/www/example-app02$ php artisan vendor:publish --tag=jetstream-views
Copied Directory [/vendor/laravel/jetstream/resources/views] To [/resources/views/vendor/jetstream]
Publishing complete.

再度ビルド

laradock@9760cc7de2d2:/var/www/example-app02$ npm run dev

サブディレクトリ設置の調整

app.bladeのパスを調整

resources/views/app.blade.php
<link rel="stylesheet" href="{{ mix('css/app.css') }}"><link rel="stylesheet" href="{{ asset(mix('css/app.css')) }}"><script src="{{ mix('js/app.js') }}" defer></script><script src="{{ asset(mix('js/app.js')) }}" defer></script>

fortify.phpのホームを修正

config/fortify.php
'home' => RouteServiceProvider::HOME,'home' => config('app.url') . RouteServiceProvider::HOME,

ログアウト後のリダイレクト先を設定

app/Providers/FortifyServiceProvider.php
use Laravel\Fortify\Contracts\LogoutResponse;public function register()
    {
        $this->app->instance(LogoutResponse::class, new class implements LogoutResponse {
            public function toResponse($request)
            {
                return redirect('/login');
            }
        });
    }

※参考:Laravel 8のログアウト後のリダイレクト先を設定 - Laravel Fortify -

Welcome.vueのDashboardリンクのhrefの設定を修正

resources/js/Pages/Welcome.vue
<inertia-link v-if="$page.props.user" href="/dashboard" class="text-sm text-gray-700 underline"><inertia-link v-if="$page.props.user" :href="route('dashboard')" class="text-sm text-gray-700 underline">

v-bindディレクティブ省略記述の:を忘れないように。

ここまでで手順に問題が無ければ、http://localhost/app02/でLaravelのWelcome画面が表示される。
右上にLoginRegisterのリンクが表示され、かつ、リンク先の画面が正しく表示されれば、JetStream Inertiaのインストール成功。

参考:動作確認

動作確認をするのであれば、Registerのリンクから登録画面にアクセスし、Name、Email、Passwordを入力してREGISTERするとよい。

  • Seederでデータ登録する場合、Userレコードと共にTeamレコードも登録する必要がある。
  • 登録後、phpMyAdminなどで、該当ユーザーのemail_verified_atに現在時刻を直接入力し、メールアドレスの確認を手動で完了にするとRoute::middleware(['verify'])を通過できる。

環境構築手順:Vuetify関連

続いてVuetifyの導入を行う。

Vuetifyのインストール

依存モジュールとVuetifyをインストール

詳細は公式ドキュメントを参照。こちらを参考に1つ1つ作業実施。

1. 本体インストール

laradock@9760cc7de2d2:/var/www/example-app02$ npm install vuetify

2. 依存パッケージインストール

laradock@9760cc7de2d2:/var/www/example-app02$ npm install sass@~1.32 sass-loader deepmerge -D

3. フォントのインストール(簡易)

app.blade.phpの<!-- Fonts -->あたりにCDNのフォントリソースリンクを追加

resources/views/app.blade.php
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" rel="stylesheet">

フォントに関する詳細は公式ドキュメントIcon Fontsを参照

4. plugins/vuetify.jsを設置

resources/jspluginsフォルダを作成、以下の内容でvuetify.jsを作成

resources/js/plugins/vuetify.js
import Vue from 'vue'
import Vuetify from 'vuetify/lib'

Vue.use(Vuetify)

const opts = {}

export default new Vuetify(opts)

5.app.jsの調整

app.jsのimport群に以下のimportを追加

resources/js/app.js
import vuetify from './plugins/vuetify';

app.jsのnew Vue()に、vuetify適用

resources/js/app.js
new Vue({
    render: (h) =>new Vue({
    vuetify,
    render: (h) =>
app.js 全文
resources/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';
import vuetify from './plugins/vuetify';

Vue.mixin({ methods: { route } });
Vue.use(InertiaPlugin);
Vue.use(PortalVue);

const app = document.getElementById('app');

new Vue({
    vuetify,
    render: (h) =>
        h(InertiaApp, {
            props: {
                initialPage: JSON.parse(app.dataset.page),
                resolveComponent: (name) => require(`./Pages/${name}`).default,
            },
        }),
}).$mount(app);

Vuetify Laravel Mix Extensionの導入

インストール

Vuetify Laravel Mix Extensionをインストール

laradock@9760cc7de2d2:/var/www/example-app02$ npm install vuetifyjs-mix-extension@0.0.20 -D

vuetify-loaderをインストール

laradock@9760cc7de2d2:/var/www/example-app02$ npm install vuetify-loader -D

webpack.mix.jsにvuetifyjs-mix-extensionの読み込みを追加

webpack.mix.js
require('vuetifyjs-mix-extension');

vuetifyjs-mix-extensionを有効化

webpack.mix.js
mix.js('resources/js/app.js', 'public/js').vue()
↓
mix.js('resources/js/app.js', 'public/js').vuetify('vuetify-loader').vue()
webpack.mix.js 全文
webpack.mix.js
const mix = require('laravel-mix');
require('vuetifyjs-mix-extension');

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel applications. By default, we are compiling the CSS
 | file for the application as well as bundling up all the JS files.
 |
 */

mix.js('resources/js/app.js', 'public/js').vuetify('vuetify-loader').vue()
    .postCss('resources/css/app.css', 'public/css', [
        require('postcss-import'),
        require('tailwindcss'),
        require('autoprefixer'),
    ])
    .webpackConfig(require('./webpack.config'));

if (mix.inProduction()) {
    mix.version();
}

反映

laradock@9760cc7de2d2:/var/www/example-app02$ npm run dev

npm run watchでも可

動作確認

Vuetifyの確認をしてみます。
都度ビルドが必要であるため、以下を実行しておきます。

laradock@9760cc7de2d2:/var/www/example-app02$ npm run watch

簡易確認

Welcome.vueにVuetifyのボタンを設置して表示を確認します。
Loginリンクを生成する<inter-link>タグの前くらいに、<v-btn>を追加します。

resources/js/Pages/Welcome.vue
<v-btn class="mx-3">サンプル</v-btn>

ブラウザで確認し、テキストではなく、Vuetifyのボタンコンポーネントが表示されれば、ひとまずVuetifyの導入に成功していることでしょう。
http://localhost/app02/

  • 本来は、<v-app><v-main>で括る必要がありますが、簡易確認ということで割愛しています。

Vuetifyらしいコンポーネントの確認

もう少し高機能なコンポーネントの確認として、Data tablesを設置してみます。

1. コントローラー作成

laradock@9760cc7de2d2:/var/www/example-app02$ php artisan make:controller AnyController
Controller created successfully.
app/Http/Controllers/AnyController.php
<?php

namespace App\Http\Controllers;

use Inertia\Inertia;
use Illuminate\Http\Request;

class AnyController extends Controller
{
    public function responseDataTables(Request $request)
    {
        $desserts = [
            ['name' => 'Frozen Yogurt',      'calories' => 159, 'fat' => 6.0,  'carbs' => 24, 'protein' => 4.0, 'iron' => '1%',],
            ['name' => 'Ice cream sandwich', 'calories' => 237, 'fat' => 9.0,  'carbs' => 37, 'protein' => 4.3, 'iron' => '1%',],
            ['name' => 'Eclair',             'calories' => 262, 'fat' => 16.0, 'carbs' => 23, 'protein' => 6.0, 'iron' => '7%',],
            ['name' => 'Cupcake',            'calories' => 305, 'fat' => 3.7,  'carbs' => 67, 'protein' => 4.3, 'iron' => '8%',],
            ['name' => 'Gingerbread',        'calories' => 356, 'fat' => 16.0, 'carbs' => 49, 'protein' => 3.9, 'iron' => '16%',],
            ['name' => 'Jelly bean',         'calories' => 375, 'fat' => 0.0,  'carbs' => 94, 'protein' => 0.0, 'iron' => '0%',],
            ['name' => 'Lollipop',           'calories' => 392, 'fat' => 0.2,  'carbs' => 98, 'protein' => 0,   'iron' => '2%',],
            ['name' => 'Honeycomb',          'calories' => 408, 'fat' => 3.2,  'carbs' => 87, 'protein' => 6.5, 'iron' => '45%',],
            ['name' => 'Donut',              'calories' => 452, 'fat' => 25.0, 'carbs' => 51, 'protein' => 4.9, 'iron' => '22%',],
            ['name' => 'KitKat',             'calories' => 518, 'fat' => 26.0, 'carbs' => 65, 'protein' => 7,   'iron' => '6%',],
        ];

        return Inertia::render('DataTables', [
            'desserts' => $desserts,
        ]);
    }
}

2. vueファイル作成

以下のファイルを作成

resources/js/Pages/DataTables.vue
<template>
  <v-app>
    <v-main>
      <v-card flat tile>
        <v-app-bar flat outlined>
          <v-toolbar-title>サンプルテーブル</v-toolbar-title>
        </v-app-bar>
        <v-data-table
            :headers="headers"
            :items="desserts"
            :items-per-page="5"
            class="elevation-1"
        ></v-data-table>
      </v-card>
    </v-main>
  </v-app>
</template>

<script>
export default {
  name: 'DataTables',
  props: ['desserts'],
  data () {
    return {
      headers: [
        {
          text: 'Dessert (100g serving)',
          align: 'start',
          sortable: false,
          value: 'name',
        },
        { text: 'Calories', value: 'calories' },
        { text: 'Fat (g)', value: 'fat' },
        { text: 'Carbs (g)', value: 'carbs' },
        { text: 'Protein (g)', value: 'protein' },
        { text: 'Iron (%)', value: 'iron' },
      ],
    }
  },
}
</script>

<style scoped>
</style>

3. ルートファイル調整

web.phpに以下のルートを追加

routes/web.php
Route::get('/data-tables', [\App\Http\Controllers\AnyController::class, 'responseDataTables'])->name('data-tables');

4. Welcome.vueに追加したボタンにルートを追加

Welcome.vueの<v-btn>hrefを追加

resources/js/Pages/Welcome.vue
<v-btn class="mx-3" :href="route('data-tables')">サンプル</v-btn>

確認

Welcomeページの「サンプルボタン」をクリックし、データテーブル画面を確認します。

Vuetifyの導入に何らかの不備があると、スタイルが適用されていなかったり、ボタンクリックなどでJavaScriptエラーが発生したりします(ブラウザの開発ツールでコンソールでJavaScriptエラーが出ていないことなども確認が必要です)。

おわりに

Laravel 8の検証がてら Laravel JetStream + Inertia にVuetifyを導入して使ってみました。

Inertia + Vueではデータの受け渡しをprops経由で行うので、データの受け取り後はSPA開発と同等の考え方を適用できそうです。下位方向へのコンポーネント分割もできますし、むしろすべてのvueファイルを分割されたコンポーネントであると捉えれば、SPAでもInertiaでも区別なくコンポーネント開発ができる気がするとかしないとか。(vuex禁止にすればより近くなりそう)

Vuetifyの場合、コンポーネントを<v-app><v-main>で囲む必要があるので、Inertiaで構成する場合、すべてのvueファイルにこのタグを記述することになります。
このあたりは、vue-routerの<router-view/>のようなApp.vueを親にして、子コンポーネントをルーティングする仕組みを自前で作ることですっきりしそうな気がするとかしないとか。(vuex禁止にすれば(以下略))

今のところ少し触ったくらいなので、引き続き検証を行いつつ、いろいろ見極めたいと思っています。

こんなところで。

Discussion