最新ソースはこちら。
https://github.com/takishita2nd/hotel-mng
この画面を見て、思ったのは、
すげぇ窮屈だな、と。
この一覧画面に表示するのは、簡単な情報だけにして、それ以外の情報は、詳細画面へのリンクをクリックすることで表示させよう、と思ったのです。
やはり避けて通れない、Vue.jsの実装。
Laravelプログラマーの宿命。
まずは、部屋一覧を取得するWebAPIを実装します。
まずはルーティング。
Route::post('/api/rooms', 'ApiController@rooms');
コントローラー。
use Illuminate\Http\Request;
use App\Repository\RoomRepository;
class ApiController extends Controller
{
public function __construct()
{
$this->middleware('auth');
$this->room = new RoomRepository();
}
public function rooms(Request $request)
{
return response()->json(['roomLists' => $this->room->getList()]);
}
}
リポジトリは既存のものを使います。
違うのは、返信するデータはJsonであること。
Laravelでは一発でJsonに変換できるんですね。便利。
Viewの実装。
<detail-component></detail-component>
とりえあず、テンプレートの実態はVue.js側に書くので、ここではVueのテンプレートを配置するタグを書きます。
そして、Vueに追加したコンポーネントを有効化します。
Vue.component('detail-component', require('./components/DetailComponent.vue'));
resource/assets/js/app.jsに追加します。
こうすることで、npm run devで追加したコンポーネントもビルドに含めてくれます。
さぁ、ここからが本番だ。
まずはテンプレートの部分
<template>
<div class="details">
<table>
<tr>
<td>
<select v-model="selectYear">
<option v-for="year in years" v-bind:value="year.value">{{ year.text }}</option>
</select>
</td>
<td>年</td>
<td>
<select v-model="selectMonth">
<option v-for="month in months" v-bind:value="month.value">{{ month.text }}</option>
</select>
</td>
<td>月</td>
<select v-model="selectRoom">
<option v-for="room in rooms" v-bind:value="room.id">{{ room.name }}</option>
</select>
</td>
</tr>
</table>
</div>
</template>
とりあえず、フィルタを行う年月と部屋を表示する実装にしています。
いずれ、予約一覧もこの中に入れます。
まだ途中なので。
<script>
export default {
data() {
return {
selectYear: 2019,
years:[
{text:'2019',value:2019},
{text:'2020',value:2020},
],
selectMonth: 1,
months:[
{text:'1',value:1},
{text:'2',value:2},
{text:'3',value:3},
{text:'4',value:4},
{text:'5',value:5},
{text:'6',value:6},
{text:'7',value:7},
{text:'8',value:8},
{text:'9',value:9},
{text:'10',value:10},
{text:'11',value:11},
{text:'12',value:12},
],
selectRoom: 0,
rooms: [],
result: [],
}
},
created: function() {
this.getRooms();
},
methods: {
getRooms: function() {
var self = this;
axios.post('/api/rooms').then(function(response){
response.data.roomLists.forEach(element => {
console.log(element.name)
self.rooms.push({id:element.id, name:element.name});
});
}).catch(function(error){
console.log("失敗しました");
});
}
}
}
</script>
年月はベタ書きです。
リストデータを定義して、v-forでoptionタグに展開する仕組み、v-modelで選択した値をバインドさせています。
この画面が読み込まれたら、axiosを使ってAjaxでデータの取得を行います。
axiosはデフォルトで組み込まれているみたい。Ajaxを行うためのライブラリです。
POSTで指定したURLに送信し、正常に受信できればthenの処理に、何かしらエラーが発生した場合はcatchの処理に移ります。
thisをselfに設定しているのは、thenやcatchの中ではthis=Vueではないので、selfにVueを退避させて置かないと、then/catchの中でVueのデータにアクセスできないためです。
で、thenの中で、レスポンスからデータを取得して、リスト化。
そのリストをテンプレート側で参照してoptionタグを作成します。
下のフィルタが今回Vueで表示させたものです。
上の部分はあとで消します。