BEAR.Sunday のマニュアルでは React をフロントエンドフレームワークとしてアプリケーションを構築する例が掲載されています。
ここでは Vue.js の webpack-simple template のバックエンドを BEAR.Sunday で構築したシングルページアプリケーションを作ってみたいと思います。
- 動作環境
-
PHP 7.1
-
BEAR.Package v1.7.0
-
Vue.js v2.5.11
-
ソースコードは GitHub で公開しています。
本エントリで紹介しきれていない詳細は完成版のソースコードと各コミットを参照してください
webpack-simple template から Vue アプリの雛形を作成する
まずは、webpack-simple template から Vue アプリの雛形を作成します。
$ vue init webpack-simple advent-vue-project
? Project name advent-vue-project
? Project description A Vue.js project
? Author
? License MIT
? Use sass? No
vue-cli · Generated "advent-vue-project".
To get started:
cd advent-vue-project
npm install
npm run dev
$ tree -a -L 1
.
├── .babelrc
├── .editorconfig
├── .gitignore
├── README.md
├── index.html
├── package.json
├── src
└── webpack.config.js
$ npm install
$ npm run dev
> advent-vue-project@1.0.0 dev /Users/Yuu/workspace/advent-calendar/advent-vue-project
> cross-env NODE_ENV=development webpack-dev-server --open --hot
Project is running at http://localhost:8080/
webpack output is served from /dist/
404s will fallback to /index.html
npm run dev
を実行するとブラウザで自動的にアプリケーションが起動します。
BEAR.Skeleton から BEAR アプリの雛形を作成する
次に BEAR.Skeleton からBEAR アプリの雛形を作成します。
また、アプリケーションのエントリ画面をHTMLとしてレンダリングするため、madapaja/twig-module をインストールします。
$ composer create-project -n bear/skeleton MyAdvent.MyProject
$ tree -a -L 1
.
├── .env
├── .gitignore
├── .php_cs.dist
├── README.md
├── autoload.php
├── bootstrap
├── composer.json
├── composer.lock
├── phpcs.xml
├── phpmd.xml
├── phpunit.xml.dist
├── public
├── src
├── tests
├── var
└── vendor
$ composer require madapaja/twig-module
TwigModule をアプリケーションにインストールし、Twigテンプレートファイルを作成する
以下のコミットを参照
https://github.com/kawanamiyuu/Kawanamiyuu.VuejsSpa/commit/5ba0dc0518b9063bd47988a4b29470750cc41312
$ php -S 127.0.0.1:8080 -t public
Vue アプリのクライアントコードを BEAR アプリに移植する
Vue アプリケーションの src
ディレクトリを src-ui
として BEAR アプリケーションに移植します。
$ tree -a -L 1
.
├── .babelrc <--
├── .env
├── .gitignore
├── .php_cs.dist
├── README.md
├── autoload.php
├── bootstrap
├── composer.json
├── composer.lock
├── node_modules <--
├── package.json <--
├── phpcs.xml
├── phpmd.xml
├── phpunit.xml.dist
├── public
├── src
├── src-ui <--
├── tests
├── var
├── vendor
└── webpack.config.js <--
webpack.config.js
を編集して Vue アプリケーションのビルド先を BEAR アプリケーションのエントリポイントである public
配下に変更します。
module.exports = {
- entry: './src/main.js',
+ entry: './src-ui/main.js',
output: {
- path: path.resolve(__dirname, './dist'),
+ path: path.resolve(__dirname, './public/dist'),
publicPath: '/dist/',
filename: 'build.js'
},
ページコンテンツを Ajax で表示する
Vue アプリのコンテンツ(「Essential Links」と「Ecosystem」のリンクURLとラベル)を Ajax でバックエンドから取得し表示します。
クライアントサイドのルーティングには vue-router を使用し、バックエンドとのAjax通信には axios を使用します。
BEAR アプリの特定の Page リソースで Json レンダリングを行うために AOP でレンダラーを JsonRenderer
に差し替えます。
// src/Module/JsonRendererInterceptor.php (新規)
use BEAR\Resource\JsonRenderer;
use BEAR\Resource\ResourceObject;
use Ray\Aop\MethodInterceptor;
use Ray\Aop\MethodInvocation;
class JsonRendererInterceptor implements MethodInterceptor
{
public function invoke(MethodInvocation $invocation)
{
$ro = $invocation->getThis();
/* @var $ro ResourceObject */
$ro->setRenderer(new JsonRenderer);
return $invocation->proceed();
}
}
// src/Module/AppModule.php (編集)
use Kawanamiyuu\VuejsSpa\Annotation\Api;
use Ray\Di\AbstractModule;
class AppModule extends AbstractModule
{
protected function configure()
{
// ...
$this->bindInterceptor(
$this->matcher->annotatedWith(Api::class),
$this->matcher->startsWith('on'),
[JsonRendererInterceptor::class]
);
// ...
}
}
// src/Resource/Page/Links.php (新規)
use BEAR\Resource\ResourceObject;
use Kawanamiyuu\VuejsSpa\Annotation\Api;
/**
* @Api
*/
class Links extends ResourceObject
{
public function onGet()
{
$this['essential_links'] = [
[
'label' => 'Core Docs',
'url' => 'https://vuejs.org'
],
// ...
];
$this['ecosystem_links'] = [
[
'label' =>'vue-router',
'url' => 'http://router.vuejs.org/',
],
// ...
];
return $this;
}
}
これで初期表示後、クライアントサイドでルーティングし(該当コミット)、かつ非同期でコンテンツを表示する(該当コミット)シングルページアプリケーションが完成しました。
↓↓↓(Welcome to Your Vue.js App
をクリック)