CakePHPでVue.jsを利用する方法
どうも、のえるです。
CakePHPはテンプレート機能も備えた便利なフレームワークですが、リクエスト・レスポンスの一般的な仕組みになっています。
そのため、シングルページアプリケーション(SPA)を実現するには工夫が必要です。
そこで今回は CakePHP + Vue.js によるSPA化の一例をご紹介します。
はじめに
今回の環境は下記のとおりです。
OS: CentOS 7.4
nginx: 1.18.0
PHP: 7.4.11
npm: 6.14.8
node: v10.15.0
CakePHP: 4.1.0
composer実装済み
インストール・設定
まずはベースとなるCakePHPをインストールしましょう。
1 2 3 |
$ composer require cakephp/cakephp |
今回インストールするのは CakePHP4 となります。
インストールが終わったら、プロジェクトの直下に vue フォルダを作り、その中に Vue.js をインストールします。
その際の構成は下記のとおりです。
続いて、layoutファイルに Vue.js の出力するファイルを読み込むように書き加えます。
1 2 3 4 5 6 7 8 9 10 |
<?php <link href="/css/app.css" rel="preload" as="style"> <link href="/css/chunk-vendors.css" rel="preload" as="style"> <link href="/js/app.js" rel="preload" as="script"> <link href="/js/chunk-vendors.js" rel="preload" as="script"> <link href="/css/chunk-vendors.css" rel="stylesheet"> <link href="/css/app.css" rel="stylesheet"> |
そして、トップ画面のテンプレートファイルにも書き加えていきましょう。
1 2 3 4 5 6 |
<?php echo $this->Html->script('chunk-vendors.js'); echo $this->Html->script('app.js'); ?> |
これで画面側が Vue.js になります。
そして、最終的に下記のような構成になります。
あとは Vue.js でビルドしたものを webroot に配置していけば完了です。
データのやりとりについて
データの送受信
CakePHPではサーバーからテンプレートへとシームレスにパラメータを渡すことができますが、今回の仕組みの場合はテンプレートが初回のみとなりますので、そのままではできません。
そこでデータのやり取りを工夫していきます。
具体的には APIの実装 によってデータをやり取りできます。
まずはAPIのためにルーティングを設定します。
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 |
<?php use Cake\Core\Configure; use Cake\Routing\Route\DashedRoute; use Cake\Routing\RouteBuilder; use Cake\Routing\Router; $routes->setRouteClass(DashedRoute::class); $routes->scope('/', function (RouteBuilder $builder) { // Top画面 $builder->connect('/', ['controller' => 'Tops', 'action' => 'index',]); // 上記に該当しないルーティングの場合 $builder->connect('/*', ['controller' => 'Tops', 'action' => 'notFound',]); $builder->fallbacks(); }); // API $routes->scope('/api', function (RouteBuilder $builder) { // ユーザー一覧取得 $builder->connect('/users/list', ['controller' => 'Users', 'action' => 'list',]); // 上記に該当しないルーティングの場合 $builder->connect('/*', ['controller' => 'Api', 'action' => 'notFound',]); }); |
そしてプログラムを記述していきます。
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 31 32 33 34 35 36 37 38 |
<?php declare(strict_types=1); namespace App\Controller; use Cake\Http\Exception\InternalErrorException; class UsersController extends AppController { public function list() { // ユーザーデータ一覧を取得 $employee = $this->Users->getList(); // 画面描画停止 $this->autoRender = false; // JSON文字列を出力 $jsonStr = json_encode($employee, JSON_PRETTY_PRINT); if(json_last_error() == JSON_ERROR_NONE){ header('Content-Type: application/json; charset=UTF-8'); header('Content-Length: '.strlen($jsonStr)); // HTTPステータスコードを設定 if(intval($statusCode) != 200) { header('HTTP', true, intval($statusCode)); } echo $jsonStr; } else{ throw new InternalErrorException('JSON文字列化 失敗'); } exit(); } } |
これで Vue.js から非同期でデータを取得することができます。
CakePHP4で非同期のデータが送れない場合
CakePHP4ではフォームデータを送信する際、CSRFが必須になっているようです。
ただ、Formを毎回作らなくても、CSRFだけ出力する方法がありますのでご紹介します。
1 2 3 |
<?= $this->request->getAttribute('csrfToken') ?> |
このCSRFをパラメータに追加してあげることでうまくデータを送ることができます。
※デフォルトのパラメータ名は _csrfToken ですが、変更することも可能です(詳細(公式))。
注意
まず前提となる知識ですが CakePHP と Vue.js のそれぞれで ルーティング機能 が存在しています。
(router.php と router/index.js)
そのため、同じURLを実装すると、URLから直接アクセスされた場合、想定しない動きをします。
(PHPのルーティング機能が優先されます)
画面側のルーティングとの重複には十分に注意しましょう。
さいごに
CakePHP と Vue.js の組み合わせに関する情報がほとんど見つかりませんでしたので書いてみました。
この記事からもっと増えればいいなと思います。
- おすすめ記事
POPULAR
のえる
Full-stack Developer