CakePHPとVue-cli2でSPA③SPAを実装する

CakePHPとVue-cli2でSPA③SPAを実装する

40 回閲覧されました

みなさんこんにちは、jonioです。

前回の解説はコントローラーからvueファイルにデータを渡してそれをブラウザに表示しました。

今回はSPAを実装します。

Vue Routerの導入

これがないとSPAができないので導入します。

Vue Routerはvueファイルからvueファイルへ遷移させる為の物という感じです。

「CakePHPのプロジェクト > resources > vue_demo」に移動して下記のコマンドを叩きます。

npm install vue-router

index.jsの設定とコンポーネントの作成

「CakePHPのプロジェクト > resources > vue_demo > src」の下の階層にrouterフォルダを作成してその下の階層にindex.jsを作成します。

そして下記の記述をします。

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue';
import About from '../views/About.vue';

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    component: Home
  },
  {
    path: '/about',
    component: About
  }
]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

export default router

9行目〜16行目がルート(URL)とどのコンポーネントを使うかの設定です。

10行目・14行目がルートで11行目・15行目がルートに対してページを表示するのに使うコンポーネントを指定しています。

ルートの設定に関してですが今回は「http://localhost/demo」にHome.vueを表示してHome.vueのリンクからAbout.vueに遷移させます。

じゃあ10行目の「/」は「/demo」にしないの?って思いませんか?

Vue Routerを使う時は「http://localhost/demo」の「/demo」がvue側の「/」に該当するみたいです。

ちなみに「/」を「/demo」にすると動作はしますが私の場合は同じvueファイルが2つ分表示されるバグが発生しました。

話を戻してHome.vueとAbout.vueをまだ作成していないので作成します。

「CakePHPのプロジェクト > resources > vue_demo > src > views」の下の階層にHome.vueとAbout.vueを作成します。

Home.vueとAbout.vueの記述は下記になります。

//Home.vue
<template>
  <div>
    <h1>Home.vue</h1>
    <router-link to="/about">Aboutページへ</router-link>
    <p>このページはHome.vueで作成しました</p>
  </div>
</template>
<style>
div{
    margin-top: 50px;
}
</style>



//Abouot.vue
<template>
  <div>
    <h1>About.vue</h1>
    <router-link to="/demo">Homeページへ</router-link>
    <p>このページはAbout.vueで作成しました</p>
  </div>
</template>

main.jsへ追記

「CakePHPのプロジェクト > resources > vue_demo > src > main.js」にVue Routerを使う為の追記をします。

import Vue from 'vue';
import  App from './App';

import router from './router';         //この行を追加

Vue.config.productionTip = false;

new Vue({
  render: h => h(App),
  router                      //この行を追加
}).$mount('#app')

App.vue

「CakePHPのプロジェクト > resources > vue_demo > src > App.vue」に追記してVue Routerの設定をします。

<template>
  <div>
    <Entry></Entry>
    
    
    //ここから追加
    <Home></Home>
    <router-view></router-view>
    //ここまで追加
    
    
  </div>
</template>

<script>
import Entry from './components/Entry.vue'
import Home from './views/Home.vue';                //この行を追加

export default {
  name: 'App',
  components: {
    Entry,
    Home,               //この行を追加
  }
}
</script>

8行目がないとVue Routerが動作しないので必ず記述しましょう。

7行目と8行目ですが「<router-view></router-view>」の部分に画面遷移(Home.vueからAbout.vue)で切り替わる内容が表示されます。

だから最初Home.vueが表示されてAbout.vueのページに遷移したときにHome.vueで表示される内容の下にAbout.vueで表示される内容が表示されます。

動作確認で実際に見てみましょう。

動作確認

「http://localhost/demo」にアクセスすると下記の表示になります。

About.vueに遷移するとHome.vueで表示される内容の下にAbout.vueで表示される内容が表示されます。

「Aboutページへ」をクリックすると表示が切り替わります、この時スパッと切り替わりますがこれがSPAを実装する時の動きになります。

この時のURLは「http://localhost/about」ですが画面を再読み込みするとエラーになります。

CakePHPはコントローラーとビューでルートが設定されるのでルートに対するコントローラーとビューがない場合はこの現象が起きます。

これはまずいのでなくしましょう。

画面再読み込み時のエラー回避

「CakePHPのプロジェクト > config > routes.php」に追記します。

$routes->scope('/', function (RouteBuilder $builder) {
    /*
     * Here, we are connecting '/' (base path) to a controller called 'Pages',
     * its action called 'display', and we pass a param to select the view file
     * to use (in this case, templates/Pages/home.php)...
     */
    $builder->connect('/*', ['controller' => 'Demo', 'action' => 'index']);       //この行を追加

    $builder->connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']);

7行目を「$routes->scope(‘/’, function (RouteBuilder $builder) {」の中の最初の行に記述して下さい、そうしないと効きません。

「/*」は「全てのURL」という意味なのですが「コントローラーとビューがなくて存在しないURLにアクセスした場合はDemoコントローラーのindexアクションが動作する、つまり下記のページが表示される」という意味になります。

試しに「http://localhost/about/aaaaaaaaaaaa」など存在しないURLにアクセスすると上記の表示になります。

これで画面読み込み時のエラー回避ができます。