LoginSignup
6
1

More than 5 years have passed since last update.

BEAR.Sunday + Vue.js で始めるシングルページアプリケーション

Last updated at Posted at 2017-12-17

BEAR.Sunday のマニュアルでは React をフロントエンドフレームワークとしてアプリケーションを構築する例が掲載されています。

ここでは Vue.js の webpack-simple template のバックエンドを BEAR.Sunday で構築したシングルページアプリケーションを作ってみたいと思います。

  • 動作環境

    • PHP 7.1
    • BEAR.Package v1.7.0
    • Vue.js v2.5.11

ソースコードは GitHub で公開しています。

本エントリで紹介しきれていない詳細は完成版のソースコードと各コミットを参照してください :sweat_smile:

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 を実行するとブラウザで自動的にアプリケーションが起動します。

スクリーンショット 2017-12-17 22.50.22.png

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

スクリーンショット 2017-12-17 22.43.17.png

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;
    }
}

これで初期表示後、クライアントサイドでルーティングし(該当コミット)、かつ非同期でコンテンツを表示する(該当コミット)シングルページアプリケーションが完成しました。

スクリーンショット 2017-12-17 23.27.44.png

↓↓↓(Welcome to Your Vue.js App をクリック)

スクリーンショット 2017-12-17 23.27.59.png

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1