Laravel + Vue.js ユーザー一覧を作成してみる(フロント編)
前回user APIを作成したので、Vue.jsを使ってフロント部分を作っていきたいと思います〜🙌
Vue CLIを使う
いつもはNuxtばっかなんですが、今回はVue CLIで作ってみたいと思います💡
ここで躓いたのは、$ vue create my-project したときに、defaultを選んじゃだめってこと(!)Manually selectって難しそうじゃん・・と思ってdefault選択したら、自分でrouterやvuex導入するの難しかった。
だいたいrouterとか必要だと思うので、manuallyにしましょう。今回はこんな感じで設定!
Userページの作成
早速、表示させるページをsrc/views/User.vue作成していく!
<template>
<div class="user">
<h1>The Prime Minister of Japan</h1>
<table class="user-table">
<tr>
<th>名前</th>
<th>写真</th>
</tr>
<tr>
<td >ここに名前を入れる</td>
<td>ここに写真を入れる</td>
</tr>
</table>
</div>
</template>
とりあえずこんな感じ??🐥
Routerの設定
次にルーティングを設定。Vue CLIでRouterを選択しているとsrc/router/index.tsファイルが既に用意されているので修正するだけ。
import User from '../views/User.vue'
const routes = [
{
path: '/user',
name: 'user',
component: User
}
]
Vuexの設定
VuexもVue CLI作成時に選択しているとデフォルトのsrc/store/index.tsファイルが用意されています。
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
user
}
})
ストアはmodulesにまとめたいので、modulesディレクトリを作成してuser.tsを作ります。こんなかんじ。TypeScript全くわからんなのでとりあえずany書いておきます。ここは今後修正していく😥
import Vue from 'vue'
const axios = require('axios');
const state = {
users: null
}
const getters = {}
const actions = {
getUsers({ commit }:any) {
axios.get('http://127.0.0.1:10080/api/user').then((res: any) => {
commit('setUsers', res.data);
})
}
}
const mutations = {
setUsers(state:any , payload: any) {
Vue.set(state, 'users', payload)
}
}
export default {
namespaced: true,
state,
getters,
actions,
mutations
}
ここで見てほしいのは、getUsersアクションでaxiosを使って前回Laravelで作ったuser APIを取得していることです。(後述しますが、この書き方だとCORSに引っかかってしまうのでうまくいきません・・😣)
次に、先ほど作成したUserコンポーネントにデータを取得する処理を追加します。
<script>
import { mapState } from 'vuex'
export default {
mounted() {
this.$store.dispatch('user/getUsers')
},
computed: {
...mapState('user', ['users'])
}
}
</script>
mounted時にuserストアをdispatchし、データを取得しています。mapStateで定義しているusersをtemplate内のtableタグ中で書いてあげれば表示されるはず・・!
<tr v-for="(user, i) in users.users" :key="i">
<td class="user-name">{{ user.name }}</td>
<td><img class="user-image" :src="user.icon_url"></td>
</tr>
CORSエラー
やっぱりクロスドメインによるエラーが出た😫
今回はLaravelとVueのリポジトリを分けており、Laravel→http://127.0.0.1:10080/ 、Vue→http://localhost:8888 で開発していたからですね・・。
Access to XMLHttpRequest at 'http://127.0.0.1:10080/api/user' from origin 'http://localhost:8888' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header has a value 'http://localhost:8888/' that is not equal to the supplied origin.
LaravelのCORS設定
こちらのQiitaを参考にさせていただきました・・!🙏
CORS用のミドルウェアを作成します。
$ php artisan make:middleware Cors
ミドルウェアの中にheaderの設定を追加します。
public function handle($request, Closure $next)
{
$url = env('APP_URL');
return $next($request)
->header('Access-Control-Allow-Origin', $url)
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
->header('Access-Control-Allow-Headers', 'Content-Type');
}
そして、src/routes/api.phpでmiddlewareを使うよう設定📝
Route::middleware(['cors'])->group( function() {
Route::options('user', function () {
return response()->json();
});
Route::get('/user', "API\UserController@index");
})
これでOKかな?設定する前のHeaderはこんな感じだったのが・・
設定後Access-Controlが設定されています!ヤッター
Vue.jsのCORS設定
次に、フロント部分のCORSも設定していきます。
まずaxios.getしているsrc/store/modules/user.tsファイルを修正
getUsers({ commit }:any) {
// 修正前 axios.get('http://127.0.0.1:10080/api/user')
axios.get('/api/user').then((res: any) => {
commit('setUsers', res.data);
})
}
/api/userしか記述していないのにデータが取得できる理由は、vue.config.jsにproxy設定を記述しているからです。このtarget部分ですね!
// vue.config.js
module.exports = {
// options...
devServer: {
public: 'localhost',
port: 8888,
disableHostCheck: true,
proxy: {
'api/': {
target: 'http://127.0.0.1:10080'
}
}
}
}
これで無事にデータが取得でき、表示成功🤗やったね!
Larabel入門を参考にしています。
スキ頂けると嬉しいです〜