目次
はじめに
現在Laravel+Vue.jsでのアプリ制作の記録です。
この記事ですることは以下です。(かなり手探りで制作しています。)
Vue.jsでのDBへの追加・編集・削除。
一番シンプルに実装できそうな会員登録/ログイン機能でまずはDBへの追加に挑戦します。
アプリ制作するならマストで越えなければいけない壁。頑張ります。
※前回までの記録。
【Laravel+Vue.js】アプリ制作の記録②プロジェクト作成
【Laravel+Vue.js】アプリ制作の記録③Vue Routerの実装
【Laravel+Vue.js】アプリ制作の記録④Vuexの実装
【Laravel+Vue.js】アプリ制作の記録⑤Vue.js側の作成
【Laravel+Vue.js】アプリ制作の記録⑥DBからのデータ取得
現状の確認
トップページの表示を確認。

CSS作成は無視。実装方法の把握に重きを置いて作っているのでこんな感じです。だいぶひどいです。笑
まずは、会員登録/ログイン画面はメインページと別で設けます。
また、ここで本格的にDB連携を目指していくので、LocalStorageを消します。
改修
上記の点を、DB実装の前にしていこうと思います。(初めてのLaravel+Vue.jsアプリ制作なので設計面が毎回変わりまくってます。。。)
Board.vueをVue Routerに取り込む
①router.jsの編集
import Vue from 'vue' import VueRouter from 'vue-router' import Register from './pages/Register.vue' import Login from './pages/Login.vue' import Board from './components/Board.vue' // add Vue.use(VueRouter) const routes = [ // add { path: '/', component: Board }, // up here { path: '/register', component: Register }, { path: '/login', component: Login } ] const router = new VueRouter({ mode: 'history', routes }) export default router
②App.vueの編集
Board.vue関連の記述を削除。
RouterViewタグをmainタグの中に移動。
headerタグにrouter-linkタグでログイン/会員登録画面のリンクを追加。
<template> <div> <header> <h1><router-link to="/">My Note</router-link></h1> // edit <router-link to="Login">ログイン</router-link> // add <router-link to="Register">会員登録</router-link> // add </header> <main> <RouterView /> </main> <footer> <div v-for="(list, index) in listing" :key="index"> <h1>{{list.created_at}}</h1> <h1>{{list.title}}</h1> </div> </footer> </div> </template> <script> export default { data() { return { listing :[] }; }, components: { }, mounted() { this.$http.get("/api/list").then(response => { this.listing = response.data; }); }, } </script>
③Login.vueの編集
<template> <div> <h3>Login</h3> </div> </template>
④Register.vueの編集
<template> <div> <h3>Register</h3> </div> </template>
http://127.0.0.1:8000/へアクセス。
Vue Routerが機能しているかも確認しつつ、こんな感じで3つのページに遷移できる状態になりました。(だいぶすっきりしました。)

Laravel+Vue.jsでのポートフォリオ制作。
現状こんな感じ。
LocalStorageでの実装をMySQLに移行するのがハードモードすぎる🙃🙃
頭パンクなので寝よう…
※Techpitのこの教材を参考にしてます。https://t.co/wmxJLrvMIs pic.twitter.com/0lUQmDQ6wq
— まさる (@masaru_pg) April 15, 2020
LocalStorageの削除
index.jsの編集
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({ state: { lists:[ { title: '', cards: [] } ], }, actions: { addlist(context, payload) { context.commit('addlist', payload) }, removelist(context, payload) { context.commit('removelist', payload) }, addCardToList(context, payload) { context.commit('addCardToList', payload) }, removeCardFromList(context, payload) { context.commit('removeCardFromList', payload) }, }, mutations: { addlist(state, payload) { state.lists.push({ title: payload.title, cards:[] }) }, removelist(state, payload) { state.lists.splice(payload.listIndex, 1) }, addCardToList(state, payload) { state.lists[payload.listIndex].cards.push({ body: payload.body }) }, removeCardFromList(state, payload) { state.lists[payload.listIndex].cards.splice(payload.cardIndex, 1) }, }, getters: { totalCardCount(state) { let count = 0 state.lists.map(content => count += content.cards.length) return count }, } }) export default store
DB登録(会員登録/ログイン機能) part1
ここからが本番です。いよいよです。言い訳はできない位環境は整ってしまいました。
今回はVue + Vue Router + Vuex + Laravelで写真共有アプリを作ろう (4) 認証APIを大いに参考にします。※テストは割愛。
APIの実装
①RouteServiceProvider.phpの編集
protected function mapApiRoutes() { Route::prefix('api') ->middleware('web') // edit ->namespace($this->namespace) ->group(base_path('routes/api.php')); }
api.phpに記載するルート定義もweb.php同様に認証関連のミドルウェアなどが適用されるようにする。
②api.phpへ追記
Route::post('/register', 'Auth\RegisterController@register')->name('register'); Route::post('/login', 'Auth\LoginController@login')->name('login'); Route::post('/logout', 'Auth\LoginController@logout')->name('logout');
③コントローラの編集
RegisterControllerの編集
use Illuminate\Http\Request; // add class RegisterController extends Controller { ~~~~ // add protected function registered(Request $request, $user) { return $user; } }
LoginController.phpの編集
use Illuminate\Http\Request; // add class LoginController extends Controller { ~~~~ // add protected function authenticated(Request $request, $user) { return $user; } protected function loggedOut(Request $request) { $request->session()->regenerate(); return response()->json(); } }
ビューの作成
上述の教材5章・6章を参考にしています。
タブ切替だとコンポーネントが1つで済む。つまりURLが1つで済むことに気付きました。
一旦教材に倣ってLogin.vueのみで実装をしてみます。
①Login.vueの編集
<template> <div class="container--small"> <ul class="tab"> <li class="tab__item" :class="{'tab__item--active': tab === 1 }" @click="tab = 1" >Login</li> <li class="tab__item" :class="{'tab__item--active': tab === 2 }" @click="tab = 2" >Register</li> </ul> <div class="panel" v-show="tab === 1"> <form class="form" @submit.prevent="login"> <label for="login-email">Email</label> <input type="text" class="form__item" id="login-email" v-model="loginForm.email"> <label for="login-password">Password</label> <input type="password" class="form__item" id="login-password" v-model="loginForm.password"> <div class="form__button"> <button type="submit" class="button button--inverse">login</button> </div> </form> </div> <div class="panel" v-show="tab === 2"> <form class="form" @submit.prevent="register"> <label for="username">Name</label> <input type="text" class="form__item" id="username" v-model="registerForm.name"> <label for="email">Email</label> <input type="text" class="form__item" id="email" v-model="registerForm.email"> <label for="password">Password</label> <input type="password" class="form__item" id="password" v-model="registerForm.password"> <label for="password-confirmation">Password (confirm)</label> <input type="password" class="form__item" id="password-confirmation" v-model="registerForm.password_confirmation"> <div class="form__button"> <button type="submit" class="button button--inverse">register</button> </div> </form> </div> </div> </template> <script> export default { data () { return { tab: 1, loginForm: { email: '', password: '' }, registerForm: { name: '', email: '', password: '', password_confirmation: '' } } }, computed: { apiStatus () { return this.$store.state.auth.apiStatus } }, methods: { login () { console.log(this.loginForm) }, async register () { await this.$store.dispatch('auth/register', this.registerForm) this.$router.push('/') }, async login () { await this.$store.dispatch('auth/login', this.loginForm) if (this.apiStatus) { this.$router.push('/') } }, async logout (context) { const response = await axios.post('/api/logout') context.commit('setUser', null) } } } </script>
②store/index.jsの編集
※後述のauth.jsをインポートします。
import auth from './auth' // add ~~~~ // gettersの直後に追記 modules: { auth } })
②store/auth.jsの作成
ここも一旦教材に倣って進めます。
const state = {} const getters = {} const mutations = {} const actions = {} export default { namespaced: true, state, getters, mutations, actions }
③CSRF対策
js/util.jsの作成、js/bootstrap.jsの編集
※教材通りなので割愛します。
おわりに
思わぬ挫折を味わいました。仕切り直して次回の記事で頑張ります。(長くなったので分けました。)
(ソースコードで追加、ここまでを記載するのに英語と日本語の入力変換が手間に感じたので今回はadd/up hereで記載しています。)
毎回設計が変わるのはLaravel+Vue.jsの連携方法がわからず、URL設計のしようがなかったことに起因しているかと思います。
このアプリ制作を終えたら反省会しながらより効率の良いアプリ制作方法を考えたいと思います。
参考
このアプリは数々のチュートリアル・教材を参考に制作しています。
参考にさせていただいた教材は以下でご紹介させていただきます。
参考教材
【Laravel x Vue.js】SPAクイズアプリケーションを作ってみよう!
Laravel(+Vue.js)でSNS風Webサービスを作ろう!
Vue + Vue Router + Vuex + Laravelで写真共有アプリを作ろう
入門Laravelチュートリアル (2) ToDoアプリケーションの設計
公式ドキュメント(英文)
コメントを残す