自分の書いたLaravel 5.4 + Vue 2.1 でSPAアプリケーション作成チュートリアルが長すぎるので要点をまとめた。
ディレクトリ構成
関係ある部分だけ。
JSが深い、なんとかならないか。
.
|-- app
| `-- Models
| `-- Article.php
|-- package.json
|-- resources
| |-- views
| | `-- app.blade.php
| `-- assets
| `-- js
| |-- app.js
| |-- bootstrap.js
| `-- components
| |-- Articles
| | `-- Index.vue
| `-- Layouts
| `-- Navbar.vue
|-- routes
|-- api.php
`-- web.php
サーバーサイド Routing
routes/web.php
<?php
Route::get('/{any}', function () {
return view('app');
})->where('any', '.*');
routes/api.php
Route::group(['middleware' => 'api'], function() {
Route::get('articles', function() {
$articles = Article::all()->take(5);
return $articles;
});
});
GET /api/articles
というルーティングが定義される
上記以外は全て、SPAのエントリーポイント app.blade.php
が返される
View
SPAのエントリーポイントである
resouces/views/app.blade.php
<!DOCTYPE html>
<html lang="{{ config('app.locale') }}">
<head>
<script>
window.Laravel = {};
window.Laravel.csrfToken = "{{ csrf_token() }}";
</script>
</head>
<body>
<div id="app">
<navbar></navbar>
<div class="container">
<router-view></router-view>
</div>
</div>
</body>
<script src="{{ mix('js/app.js') }}"></script>
</html>
<router-view></router-view>
が vue-router
によって動的に変わる
JS
app.js
クライアントサイドのルーティングとComponentを定義する。
resources/assets/js/app.js
import Vue from 'vue'
import VueRouter from 'vue-router'
require('./bootstrap')
Vue.use(VueRouter)
Vue.component('navbar', require('./components/Layouts/Navbar.vue'))
const router = new VueRouter({
mode: 'history',
routes: [
{ path: '/',
component: require('./components/Articles/Index.vue')
}
]
})
const app = new Vue({
router
}).$mount('#app')
bootstrap.js
マニフェスト的なファイル
resources/assets/js/bootstrap.js
// ...
window.axios = require('axios')
window.axios.defaults.headers.common = {
'X-CSRF-TOKEN': window.Laravel.csrfToken,
'X-Requested-With': 'XMLHttpRequest'
}
Vue.prototype.$http = axios
// ...
Vue Component
MVCのVに当たる部分。
resources/assets/js/components/Layouts/Navbar.vue
<template>
<nav class="navbar navbar-default">
<li>
<router-link to="/about">About</router-link>
</li>
</nav>
</template>
resources/assets/js/components/Articles/Index.vue
<template>
<div v-for="article in articles">
<h1>
<router-link :to="'/articles/' + article.id">{{ article.title }}</router-link>
</h1>
<p>
{{ article.content }}
</p>
</div>
</template>
<script>
export default {
created() {
this.fetchArticles()
},
data() {
return {
articles: []
}
},
methods: {
fetchArticles() {
this.$http({
url: '/api/articles',
method: 'GET'
}).then(res => {
this.articles = res.data
})
}
}
}
</script>
走り書きだなあ・・・
でもこれで概念は理解できた。