この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:6
ページ更新者:T
更新日時:2026-06-11 07:29:05

タイトル: Vue.jsと連携するSPA実行環境構築
SEOタイトル: 【Laravel】Vue.jsと連携するSPA実行環境構築

この本文には実行可能なタグ等が含まれるため、安全のためHTMLソースとして表示しています。本文データは変更していません。

<table border="1" cellpadding="1" cellspacing="1" style="width:1000px">
	<thead>
		<tr><th style="background-color:#f39c12;color:#ffffff;text-align:left">この記事の要点</th></tr>
	</thead>
	<tbody>
		<tr>
			<td style="background-color:#fef9e7">
			<ul>
				<li>Laravel + Vue.js で <strong>SPA 実行環境</strong>を構築する手順</li>
				<li>Web ルーティング: Laravel 側を<strong>無効化</strong>し、すべて <code>app.blade.php</code> に集約</li>
				<li>クライアントルーティング: <strong>vue-router</strong> 側で行う</li>
				<li>API: <strong><code>routes/api.php</code> 経由で /api/* を使う</strong></li>
			</ul>
			</td>
		</tr>
	</tbody>
</table>

<p>&nbsp;</p>



<h2>前提</h2>

<p>・Laravelプロジェクトを作成済み (まだの場合は<a href="https://jpn.itlibra.com/article?id=10857">こちら</a>のページを参照)</p>

<p>・Vue.jsとの連携とvue-routerのインストール&nbsp;(まだの場合は<a href="https://jpn.itlibra.com/article?id=21298">こちら</a>のページを参照)</p>

<p>・SPAの実行環境を構築するだけです。SPAの様々な記述方法は他のページを参照してください。</p>

<p>&nbsp;</p>

<h2>サーバーサイド(Laravel)のwebルーティングの無効化</h2>

<p><span style="color:#e74c3c"><strong>webのルーティング処理はVue.js側で行う</strong></span>のでLaravel側のルーティング処理は不要となる。</p>

<p><span style="color:#e74c3c">※APIのルーティング(routes/api.php)は使用する(後述)</span></p>

<p>全てにリクエストに対して共通のレイアウト(resources/views/layouts/<strong>app.blade.php</strong>)を返すようにする。</p>

<table border="1" cellpadding="1" cellspacing="1" style="width:500px">
	<thead>
		<tr>
			<th scope="col" style="background-color:#ffffff"><span style="color:null">routes/</span><span style="color:#e74c3c">web.php</span></th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td style="background-color:#000000">
			<p><span style="color:#ffffff">Route::get('</span><span style="color:#f1c40f">/{any}</span><span style="color:#ffffff">', function () {</span></p>

			<p><span style="color:#ffffff">&nbsp; &nbsp; return view(</span><span style="color:#2ecc71">'app'</span><span style="color:#ffffff">);</span></p>

			<p><span style="color:#ffffff">})</span><span style="color:#f1c40f">->where('any', '.*')</span><span style="color:#ffffff">;</span></p>
			</td>
		</tr>
	</tbody>
</table>

<p>&nbsp;</p>

<h2>共通レイアウトの作成</h2>

<p>Veu.jsを使うための最低限の設定と必要なheadタグ内の要素を記述すればよい。</p>

<table border="1" cellpadding="1" cellspacing="1" style="width:500px">
	<thead>
		<tr>
			<th scope="col" style="background-color:#ffffff">resources/views/<span style="color:#e74c3c"><strong>app.blade.php</strong></span></th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td style="background-color:#000000">
			<p><span style="color:#ffffff"><!DOCTYPE html></span></p>

			<p><span style="color:#ffffff"><html lang="{{ app()->getLocale() }}"></span></p>

			<p><span style="color:#ffffff">&nbsp; &nbsp;&nbsp;<head></span></p>

			<p><span style="color:#ffffff">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<meta charset="utf-8"></span></p>

			<p><span style="color:#ffffff">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<!-- CSRF Token --><br />
			&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<meta name="csrf-token" content="{{ csrf_token() }}"></span></p>

			<p><span style="color:#ffffff">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<!-- CSS --><br />
			&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<link href="{{ asset('css/app.css') }}" rel="stylesheet"></span></p>

			<p><span style="color:#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</head></span></p>

			<p><span style="color:#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;<body></span></p>

			<p><span style="color:#f1c40f">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<div id="app"></span></p>

			<p><span style="color:#f1c40f">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<router-view></router-view></span></p>

			<p><span style="color:#f1c40f">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div></span></p>

			<p><span style="color:#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<!-- Scripts --></span><br />
			<span style="color:#f1c40f">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<script src="{{ mix('js/app.js') }}"></script></span></p>

			<p><span style="color:#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</body></span></p>

			<p><span style="color:#ffffff"></html></span></p>

			<p>&nbsp;</p>
			</td>
		</tr>
	</tbody>
</table>

<p>&nbsp;</p>

<h2>サーバーサイド(Laravel)のAPIを作成</h2>

<p>テスト用にDBから適当なデータを取得するAPIを作成する。</p>

<p>&nbsp;</p>

<p>まずは適当なAPIルーティングを作成する。</p>

<table border="1" cellpadding="1" cellspacing="1" style="width:500px">
	<thead>
		<tr>
			<th scope="col" style="background-color:#ffffff"><span style="color:null">routes/</span><span style="color:#e74c3c">api.php</span></th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td style="background-color:#000000">
			<p><span style="color:#ffffff">Route::get('articles', 'Article\ArticleController@getArticles');</span></p>
			</td>
		</tr>
	</tbody>
</table>

<p>&nbsp;</p>

<p>適当なコントローラーを作成する。</p>

<table border="1" cellpadding="1" cellspacing="1" style="width:500px">
	<thead>
		<tr>
			<th scope="col" style="background-color:#ffffff">app/Http/Controllers/Article/<span style="color:#e74c3c">ArticleController.php</span></th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td style="background-color:#000000">
			<p><span style="color:#ffffff"><?php<br />
			namespace App\Http\Controllers\Article;</span></p>

			<p><span style="color:#ffffff">use App\Http\Controllers\Controller;<br />
			use App\Models\Article;<br />
			use Illuminate\Http\Request;<br />
			use Log;</span></p>

			<p><span style="color:#ffffff">class ArticleController extends Controller<br />
			{&nbsp; &nbsp;&nbsp;<br />
			&nbsp; &nbsp; public function getArticles(Request $request){<br />
			&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<br />
			&nbsp; &nbsp; &nbsp; &nbsp; $articles = Article::orderBy('update_datetime', 'DESC')<br />
			&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ->limit(3)<br />
			&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ->get();<br />
			&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<br />
			&nbsp; &nbsp; &nbsp; &nbsp; return response()->json($articles);<br />
			&nbsp; &nbsp; }<br />
			}</span><br />
			&nbsp;</p>
			</td>
		</tr>
	</tbody>
</table>

<p>&nbsp;</p>

<p>適当なモデルを作成する。(マイグレーションするなり直にcreate tableしてテーブル作成をしておく)</p>

<p>※titleカラムを作成しておくこと。</p>

<table border="1" cellpadding="1" cellspacing="1" style="width:500px">
	<thead>
		<tr>
			<th scope="col" style="background-color:#ffffff">app/model/<span style="color:#e74c3c">Article.php</span></th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td style="background-color:#000000">
			<p><span style="color:#ffffff"><?php</span></p>

			<p><span style="color:#ffffff">namespace App\Models;</span></p>

			<p><span style="color:#ffffff">use Illuminate\Database\Eloquent\Model;</span></p>

			<p><span style="color:#ffffff">class Article extends Model<br />
			{<br />
			&nbsp; &nbsp; protected $table = 'article';</span></p>

			<p><span style="color:#ffffff">&nbsp; &nbsp; protected $primaryKey = 'article_id';</span></p>

			<p><span style="color:#ffffff">&nbsp; &nbsp; public $incrementing = 'article_id';</span></p>

			<p><span style="color:#ffffff">&nbsp; &nbsp; protected $guarded = [<br />
			&nbsp; &nbsp; &nbsp; &nbsp; 'created_at',<br />
			&nbsp; &nbsp; &nbsp; &nbsp; 'updated_at',<br />
			&nbsp; &nbsp; ];<br />
			}</span><br />
			&nbsp;</p>
			</td>
		</tr>
	</tbody>
</table>

<p>&nbsp;</p>

<h2>ローカルサーバーの起動</h2>

<p>以下の2つのコマンドをそれぞれ別窓で実行してローカルサーバーを起動する。</p>

<table border="1" cellpadding="1" cellspacing="1" style="width:1000px">
	<tbody>
		<tr>
			<td style="background-color:#000000">
			<p><span style="color:#ffffff">php artisan serve</span></p>
			</td>
		</tr>
	</tbody>
</table>

<p>&nbsp;</p>

<table border="1" cellpadding="1" cellspacing="1" style="width:1000px">
	<tbody>
		<tr>
			<td style="background-color:#000000">
			<p><span style="color:#ffffff">npm run hot</span></p>
			</td>
		</tr>
	</tbody>
</table>

<p>&nbsp;</p>

<h2>Veu.jsでルーティングを作成</h2>

<table border="1" cellpadding="1" cellspacing="1" style="width:500px">
	<thead>
		<tr>
			<th scope="col" style="background-color:#ffffff"><span style="color:null">resources/assets/js/</span><span style="color:#e74c3c">app.js</span></th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td style="background-color:#000000">
			<p><span style="color:#ffffff">import Vue from 'vue'<br />
			import VueRouter from 'vue-router'</span></p>

			<p><span style="color:#ffffff">require('./bootstrap');</span></p>

			<p><span style="color:#ffffff">Vue.use(VueRouter)</span></p>

			<p><span style="color:#ffffff">const router = new VueRouter({<br />
			&nbsp; &nbsp; mode: 'history',<br />
			&nbsp; &nbsp; routes: [<br />
			&nbsp; &nbsp; &nbsp; &nbsp; { path: '/articles', component: require('./components/Articles.vue') },<br />
			&nbsp; &nbsp; ]<br />
			})</span></p>

			<p><span style="color:#ffffff">const app = new Vue({<br />
			&nbsp; &nbsp; el: '#app',<br />
			&nbsp; &nbsp; router,<br />
			})</span></p>
			</td>
		</tr>
	</tbody>
</table>

<p>&nbsp;</p>

<h2>ビューの作成とAPIの呼び出し</h2>

<table border="1" cellpadding="1" cellspacing="1" style="width:500px">
	<thead>
		<tr>
			<th scope="col" style="background-color:#ffffff"><span style="color:null">resources/assets/js/components/</span><span style="color:#e74c3c">Articles.vue</span></th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td style="background-color:#000000">
			<p><span style="color:#ffffff"><template></span></p>

			<p><span style="color:#ffffff">&nbsp; &nbsp; <div></span></p>

			<p><span style="color:#ffffff">&nbsp; &nbsp; &nbsp; &nbsp; <ul></span></p>

			<p><span style="color:#ffffff">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <li v-for="article in articles"></span></p>

			<p><span style="color:#ffffff">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {{ article.title }}</span></p>

			<p><span style="color:#ffffff">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </li></span></p>

			<p><span style="color:#ffffff">&nbsp; &nbsp; &nbsp; &nbsp; </ul></span></p>

			<p><span style="color:#ffffff">&nbsp; &nbsp; </div></span></p>

			<p><span style="color:#ffffff"></template></span></p>

			<p><span style="color:#ffffff"><script></span></p>

			<p><span style="color:#ffffff">&nbsp; &nbsp; export default {</span></p>

			<p><span style="color:#ffffff">&nbsp; &nbsp; &nbsp; &nbsp; created() {</span></p>

			<p><span style="color:#ffffff">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.getArticles()</span></p>

			<p><span style="color:#ffffff">&nbsp; &nbsp; &nbsp; &nbsp; },</span></p>

			<p><span style="color:#ffffff">&nbsp; &nbsp; &nbsp; &nbsp; data() {</span></p>

			<p><span style="color:#ffffff">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return {</span></p>

			<p><span style="color:#ffffff">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; articles: []</span></p>

			<p><span style="color:#ffffff">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</span></p>

			<p><span style="color:#ffffff">&nbsp; &nbsp; &nbsp; &nbsp; },</span></p>

			<p><span style="color:#ffffff">&nbsp; &nbsp; &nbsp; &nbsp; methods: {</span></p>

			<p><span style="color:#ffffff">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; getArticles() {</span></p>

			<p><span style="color:#ffffff">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; axios<br />
			&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .get('/api/articles')<br />
			&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .then(res => &nbsp;{<br />
			&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.articles = res.data<br />
			&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })</span></p>

			<p><span style="color:#ffffff">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</span></p>

			<p><span style="color:#ffffff">&nbsp; &nbsp; &nbsp; &nbsp; }</span></p>

			<p><span style="color:#ffffff">&nbsp; &nbsp; }</span></p>

			<p><span style="color:#ffffff"></script></span></p>
			</td>
		</tr>
	</tbody>
</table>

<p>&nbsp;</p>

<p>以上の設定で「<a href="http://localhost:8000/articles">http://localhost:8000/articles</a>」にアクセスするとarticleテーブルのtitle一覧が表示される。</p>

<p>&nbsp;</p>