LaravelをAPIに専念させてVue.jsにフロントエンドを任せる、という構成でwebサイトを作ることを考えます。そうした時、Laravel側のルーティングはおおよそ次の様になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | // web.php Route::group( static function () { // ログイン Route::get( 'login' , 'Auth\LoginController@showLoginForm' )->name( 'login' ); Route::post( 'login' , 'Auth\LoginController@login' )->name( 'login' ); Route::post( 'logout' , 'Auth\LoginController@logout' )->name( 'logout' ); // 本体 Route::middleware([ 'auth:web' ])->group( static function () { // API Route::prefix( 'api' )->name( 'api.' )->group( static function () { Route::get( 'member/search' , 'MemberController@search' )->name( 'member.search' ); Route::apiResource( 'member' , 'MemberController' , [ 'show' , 'update' ]); }); // Vue.jsアプリへのアクセス Route::get( '/{any}' , static function () { return view( 'pages.index' ); })->where( 'any' , '.*' ); }); } ); |
末尾の
1 2 3 | Route::get( '/{any}' , static function () { return view( 'pages.index' ); })->where( 'any' , '.*' ); |
で上からルーティングを読んでいき、当てあはまらなかった全てのルーティングをキャッチしてindexページを返します。indexページの中にはVue.jsのアプリページが入っています。
このようにするとLaravel側はVue.js側のルーティングに対してほぼ完全に無関心になります。無関心故に404も返せなくなります。Vue.js側で404を実装する必要が出てきます。
まずはルーティングにキャッチできなかった謎URLを全て404にするルーティングの定義です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | import Vue from 'vue' ; import Router, {RouterOptions} from 'vue-router' ; import IndexPage from '@/pages/Index' ; import MemberIndexPage from '@/pages/member/Index' ; Vue.use(Router); const options: RouterOptions = { mode: 'history' , routes: [ { path: '/' , name: 'root' , component: IndexPage, }, { path: '/member' , name: 'member' , component: MemberIndexPage, }, { // ここで上のルーティングに該当しなかったものを全てNotFoundPage送り path: '*' , name: 'notFound' , component: NotFoundPage, }, ], }; export default new Router(options); |
少し手間なのがAPIの結果によってページが存在するかしないか判断する場合です。そういった際はbeforeEnterというルート単位ガード処理を定義し、その中でリダイレクトさせるとNotFoundPage送りにできます。
ナビゲーションガード | Vue Router
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | { path: '/member/:id' , name: 'memberShow' , component: MemberShow, beforeEnter: (to, from, next) => { MemberRepository.find(to.params.id).then((member) => { to.meta.member = member; next(); }). catch ((e) =>{ // APIの結果が例外処理ならば、とりあえず404送り。/404に該当するルーティングはないのでNotFoundPage送り next({path: '/404' , query: {msg: '存在しない会員のIDです' }}); }); }, props: (route)=> { return {member: route.meta.member}; }, }, |