1. 必要な依存関係のインストール
既存の CakePHP5 プロジェクトディレクトリに移動し、必要な依存関係をインストールします。
cd your_existing_cakephp5_project_directory
npm init -y
npm install vue
2. Webpack の設定
Vue.js を使用するために、Webpack の設定を行います。
2.1 Webpack のインストール
npm install --save-dev webpack webpack-cli webpack-dev-server vue-loader@next vue-template-compiler css-loader style-loader
2.2 Webpack の設定ファイルを作成
プロジェクトのルートディレクトリに webpack.config.js
を作成し、以下の内容を追加します。
const path = require('path');
const { VueLoaderPlugin } = require('vue-loader');
const webpack = require('webpack');
module.exports = {
mode: 'development',
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'webroot/js'),
filename: 'bundle.js',
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
}
]
},
plugins: [
new VueLoaderPlugin(),
new webpack.DefinePlugin({
__VUE_OPTIONS_API__: JSON.stringify(true),
__VUE_PROD_DEVTOOLS__: JSON.stringify(false),
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: JSON.stringify(false)
})
],
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm-bundler.js'
},
extensions: ['.js', '.vue', '.json']
},
devServer: {
static: path.join(__dirname, 'webroot'),
compress: true,
port: 9000
}
};
3. Vue.js アプリケーションの作成
3.1 src
ディレクトリに main.js
を作成します。
src/main.js
:
import { createApp } from 'vue';
import App from './App.vue';
createApp(App).mount('#app');
3.2 src
ディレクトリに App.vue
ファイルを作成します。
src/App.vue
:
<template>
<div id="app" class="container">
<h1 class="my-3">Hello Vue with Bootstrap 5</h1>
<button class="btn btn-primary">Bootstrap Button</button>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
/* スタイルを追加する場合はここに記載 */
</style>
4. ビルドスクリプトの設定
package.json
の scripts
セクションにビルドスクリプトを追加します。
"scripts": {
"build": "webpack",
"start": "webpack serve"
}
5. ビルドとサーバーの起動
以下のコマンドでビルドを実行し、開発サーバーを起動します。
npm run build
npm start
6. CakePHP ビューへの組み込み
CakePHP のビューで生成された bundle.js
を読み込むようにします。以下のレイアウトファイルに bundle.js
のスクリプトタグを追加します。
templates/layout/default.php
:
<!DOCTYPE html>
<html lang="ja">
<head>
<?= $this->Html->charset() ?>
<?= $this->Html->meta('icon') ?>
<?= $this->Html->meta('format-detection', 'telephone=no') ?>
<?= $this->element('header/meta') ?>
<title><?= $this->Page->getPageTitle($page_name) ?></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<?= $this->Html->css('https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css', [
'integrity' => 'sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN',
'crossorigin' => 'anonymous'
]) ?>
<?= $this->Html->css('https://cdnjs.cloudflare.com/ajax/libs/bootstrap-icons/1.11.3/font/bootstrap-icons.min.css', [
'integrity' => 'sha512-dPXYcDub/aeb08c63jRq/k6GaKccl256JQy/AnOq7CAnEZ9FzSL9wSbcZkMp4R26vBsMLFYH4kQ67/bbV8XaCQ==',
'crossorigin' => 'anonymous',
'referrerpolicy' => 'no-referrer'
]) ?>
<?= $this->fetch('meta') ?>
<?= $this->fetch('css') ?>
</head>
<body>
<?= $this->element('header') ?>
<?= $this->Flash->render() ?>
<main id="main_container">
<div id="app"></div> <!-- この要素が必要 -->
<?= $this->fetch('content') ?>
<?= $this->element('footer_bp') ?>
</main>
<?= $this->Html->script('https://code.jquery.com/jquery-3.7.1.min.js', [
'block' => 'script',
'integrity' => 'sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=',
'crossorigin' => 'anonymous'
]) ?>
<?= $this->Html->script('https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/js/bootstrap.min.js', [
'block' => 'script',
'integrity' => 'sha512-ykZ1QQr0Jy/4ZkvKuqWn4iF3lqPZyij9iRv6sGqLRdTPkY69YX6+7wvVGmsdBbiIfN/8OdsI7HABjvEok6ZopQ==',
'crossorigin' => 'anonymous',
'referrerpolicy' => 'no-referrer'
]) ?>
<?= $this->Html->script('bundle.js', ['block' => 'script']) ?><!-- この要素が必要 -->
<?= $this->fetch('script') ?>
<?= $this->element('footer_tag') ?>
</body>
</html>