【中上級者向け】Laravel API+Vue.jsで作るモダンSPA構築ガイド
この記事で学べること
- Laravel API リソースと認証トークンの基本設定
- Vue 3+Axios(または Inertia.js)でシンプルなシングルページアプリを実装
- 音声読み上げやキーボード操作に配慮したアクセシビリティ強化
- 実践的サンプルコードとプロジェクト構成のポイント
- デプロイ前に押さえたい最適化&セキュリティチェックリスト
想定読者
- バックエンドもフロントエンドも自在に扱いたい中上級エンジニア
- Laravel と Vue の連携に興味があるフルスタック開発者
- モダンSPAのアクセシビリティ対応を学びたいプロジェクトリーダー
アクセシビリティレベル:★★★★★
画面リーダー対応、キーボードフォーカストラップ、aria-liveによる動的通知など網羅
はじめに:なぜ SPA+API が今求められるのか
近年、ユーザー体験(UX)の向上や開発効率の観点から、
サーバーサイドの API とクライアントサイドの JavaScript を組み合わせた
シングルページアプリケーション(SPA)が主流になりつつあります。
Laravel は堅牢な API を、Vue.js はリッチなインターフェースを
シンプルに実装できるフレームワークとして人気を集めています♡
- 即時更新:部分的な再描画でストレスフリー
- 分離開発:バックエンド/フロントエンドを並行して進行
- 再利用性:API だけで社内ツールやモバイルアプリにも展開可能
この記事では、初期セットアップからトークン認証、コンポーネント設計、
アクセシビリティ配慮まで、一気通貫で解説します。
1. Laravel API の準備:リソースとトークン認証
1.1 API リソースの定義
// app/Http/Controllers/Api/PostController.php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function index()
{
return Post::orderBy('created_at','desc')->get();
}
public function store(Request $request)
{
$data = $request->validate([
'title' => 'required|string|max:100',
'body' => 'required|string',
]);
return Post::create($data);
}
}
routes/api.php
にルートを登録し、api/posts
経由で JSON を返却。- Eloquent の API リソースを利用すれば、さらに整形も可能。
1.2 Sanctum でトークン認証を有効化
composer require laravel/sanctum
php artisan vendor:publish --tag=sanctum-migrations
php artisan migrate
// app/Models/User.php
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, Notifiable;
// …
}
// routes/api.php
Route::post('/login', [AuthController::class,'login']);
Route::middleware('auth:sanctum')->group(function(){
Route::apiResource('posts', PostController::class);
});
- トークンは
user->createToken('token-name')->plainTextToken
で発行。 - フロントからは Authorization ヘッダに
Bearer トークン
を付与してリクエスト。
2. Vue 3+Axios でフロント実装
2.1 プロジェクト構成例
frontend/
├─ src/
│ ├─ components/
│ │ ├─ PostList.vue
│ │ └─ PostForm.vue
│ ├─ composables/
│ │ └─ useAuth.js
│ ├─ App.vue
│ └─ main.js
└─ package.json
- components/:画面ごとではなく、再利用可能な UI パーツを配置
- composables/:認証トークン管理や API 呼び出しを共通化
2.2 Axios のセットアップ例
// src/main.js
import { createApp } from 'vue';
import App from './App.vue';
import axios from 'axios';
axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.withCredentials = true;
createApp(App).mount('#app');
// src/composables/useAuth.js
import axios from 'axios';
import { ref } from 'vue';
export function useAuth() {
const token = ref(localStorage.getItem('token') || '');
axios.interceptors.request.use(config => {
if (token.value) config.headers.Authorization = `Bearer ${token.value}`;
return config;
});
const login = async (credentials) => {
const res = await axios.post('/login', credentials);
token.value = res.data.token;
localStorage.setItem('token', token.value);
};
return { token, login };
}
- インターセプターで Authorization ヘッダを一元設定。
- トークンは
localStorage
に保管し、リロード後も継続利用。
3. アクセシビリティ強化ポイント
3.1 aria-live で動的更新を通知
<!-- PostList.vue -->
<template>
<ul>
<li v-for="post in posts" :key="post.id">{{ post.title }}</li>
</ul>
<div aria-live="polite" class="sr-only">
{{ posts.length }} 件の投稿が表示されています
</div>
</template>
aria-live="polite"
で投稿数の変化を画面リーダーにアナウンス。
3.2 キーボードフォーカストラップ
<!-- Modal.vue の一部 -->
<div
role="dialog" aria-modal="true" tabindex="-1"
@keydown.tab.prevent="trapFocus"
ref="dialog"
>
<!-- フォーカス可能要素を循環させる処理 -->
</div>
- モーダル内では Tab キーが範囲外に出ないよう制御。
- Esc キーで閉じるハンドラも必ず実装。
4. デプロイ前の最適化&セキュリティチェック
- API:Rate Limiting(Throttle)設定で過負荷防止
- CORS:必要最低限のオリジンのみ許可
- フロント:コード分割(dynamic import)で初回表示を高速化
- HTTPS:必ず SSL/TLS を適用
- 環境変数:トークン有効期限やキーは
.env
管理
5. まとめと次のステップ
- Laravel API:Sanctum でセキュアなトークン認証を実現
- Vue 3+Axios:インターセプター活用で認証連携をスマートに
- アクセシビリティ:aria-live やキーボード制御で誰も使いやすく
- 最適化/セキュリティ:Rate Limit や CORS、HTTPS で守りの堅牢化
この記事をもとに、モダンなSPAアーキテクチャをマスターしてみてくださいね♡
さらに Inertia.js や Vue Router を組み合わせれば、
よりリッチで直感的なユーザー体験が実現できます。