Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practice to integrate VueJS with CakePHP 3

I would like to know what will be the best way to integrate Vue.js framework inside a CakePHP 3 application?

I'm hoping that there's a way to benefit from all the tools coming with VueCLI (webpack,ect..) while still working without the need to copy generated file inside the CakePHP application.

So what is the most streamlined process to develop an application using CakePHP 3 as the backend and Vue.js as the frontend inside the same project.

Thanks a lot!

like image 250
Danny Nadeau Avatar asked May 31 '18 17:05

Danny Nadeau


2 Answers

Ok, here is a quick setup :

1) install vuejs in a sub dir of webroot (like webroot/vuedev)

2) config your vue router to use history mode :

export default new Router({
  mode:'history',
  routes: [

3) Change the assetsPublicPath of the build zone to assetsPublicPath: '', in webroot/vuedev/config/index.js

4) Because in dev mode your app is running on localhost:8080 and your ajax call your-domain.dev you will have CORS issues. Add header to your ajax calls :

axios.get(url,{headers: {"Access-Control-Allow-Origin": "*"}}).then...

use a prefix "api" for your ajax calls : your-domain.xxx/api/controller/action...

5) Change routing of cakePHP to use REST api : in config/routes.php :

// add api prefix

Router::prefix('api', function ($routes) {
    $routes->fallbacks(DashedRoute::class);
});

// change default route :

Router::scope('/', function (RouteBuilder $routes) {

    $routes->connect('/:page',['controller'=>'Pages','action'=>'display']); 

    $routes->connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']);
    $routes->connect('/pages/*', ['controller' => 'Pages', 'action' => 'display']);
    $routes->fallbacks(DashedRoute::class);
});

Ajax calls your-domain.xxx/api/controller/action will be proceed normaly. Every calls to your-domain.com/xxx will be transfert to the controller pages, action display.

6) Copy the index.html content of your webroot/vuedev to your template home (src/Template/Pages/home.ctp) and add to your display action of your controller.

$this->viewBuilder()->setLayout(false); 

7) For production : Launch the building process :

npm run build. 

Copy webroot/vuedev/dist/static to webroot/static

Copy the content of webroot/vuedev/dist/index.html to your src/Template/Pages/home.ctp

If someone call manualy a specific page or refresh the browser (ie: your-domain.xxx/Products) your pages controller will send the index.html content. You can add te param :page to your template/Pages/home.ctp in a global var in script tag to be used by the router :

<script>var routeToJump=<?php echo $yourvar;?>; </script>

And in your App.vue :

export default {
  name: 'App',
  created() {
    this.$router.push(routeToJump);
    ...
like image 106
Charles G Avatar answered Sep 28 '22 06:09

Charles G


You won't get away without copying files around except you don't care about size and loading times. Just throw everything in your webroot/js then load all the needed files in your views and you're OK. Vue is JS, just JS, nothing more. Also I don't see why the coping, which happens automatically, is bad.

IMO JS apps are a huge mess glued somehow together by build scripts.

If you care about an optimized build use npm and webpack and configure Webpack to build your Vue app and define your webroot as target folder. Webpack will allow you to auto-split files and gives you a warning when a file becomes to big.

We've put all our frontend stuff in /resources/js and /scss and so on and build it and have hot reloading active so we can see changes right after we hit save. This is just for development. When deploying to our live systems the JS is build on the live system, we don't add any of the builds to our git repository.

However the "building" of JS apps for the frontend is a pain in the ass if you don't stick to a 100% pure JS frontend app. There is no real standard way of doing it. Even "import" has its quirks and feels more like a hack than a good solution to the problem nor does it solve the issue of packaging files to reduce requests and file size.

Once you've got all the crap glued together it usually works nice but it's really sad that in 2018 there isn't a recommended standard for building JS for web apps. I really hope the way things are done today is going to die soon in favor of Web Assembly.

If you don't want to use Webpack there is require.js and others as well but for us webpack worked the best.

like image 27
floriank Avatar answered Sep 28 '22 08:09

floriank