Blog

I write on blua.blue, dev.to and others

VueJS & neoan3: a love story.

originally posted on blua.blue

play tutorial video

To stay aligned with the video, we will call our app & project-folder "video" and our frame "vuePhp"

What is the challenge?

I noticed that division between front- & back-end, packaging tools like webpack as well as containerized delivery has created many over-engineered solutions to the basic development flow of applications. As a full-stack developer, I often develop the front- and back-end simultaneously while requiring to serve resources

  • dynamic
  • selective (don't want a particular view/endpoint to load unused components)
  • fast
  • without additional development servers, build processes etc.

Manipulating the way neoan3 serves files

Whether it be the serve.file endpoint, the autoloader or the conditional rendering: neoan3 doesn't seem to be set up to work nicely with VueJS. But then there is the layer of the frames that let's us easily alter the very way the core executes the rendering process. What we will do is combining the cli-tool's built-in capability to use templates with combined with the extensibility of core functionality provided by a neoan3 frame.

In order to do this we will

  1. create a new neoan3 app
  2. create a new neoan3 frame
  3. create cli-templates

1. create a new neoan3 app

If you haven't already, please install the cli globally (npm i -g neoan3-cli). Then, after navigating to a new folder in our localhost (optional, you can also use neoan3's server.php to run the app), we create a new project using our terminal:

neoan3 new app video

2. create a new neoan3 frame

After running neoan3 new frame vuePhp, we want to extend the constructor and the output of the core:

<?php
/* Generated by neoan3-cli */

namespace Neoan3\Frame;

use Neoan3\Core\Serve;

class VuePhp extends Serve
{
    function __construct(){
        parent::__construct();
    }
    function output($params = []){
        parent::output($params);
    }
}

After installing vue (npm i vue), we want to include the framework. The file "vue/dist/vue.js" includes vue's development tools while the file "vue/dist/vue.min.js" does not. So what we want to do is to include the development environment when we are serving via localhost:

if($_SERVER['HTTP_HOST'] == 'localhost'){
        $this->includeJs(base . 'node_modules/vue/dist/vue.js');
} else {
        $this->includeJs(base . 'node_modules/vue/dist/vue.min.js');
}

We can place this snippet in the constructor after calling the parent's constructor.

neoan3's default hooks for views are

  • header
  • main
  • footer

What we want to achieve is to wrap the complete main container in a vue element and subsequently use components. To achieve that, we will directly write to the js stream of neoan3 and overwrite the main container in the output function before we execute the parent function:

$this->js .= 'new Vue({el:"#root"});';
$this->main = '<div id="root">' . $this->main . '</div>';

NOTE: there are cleaner solutions, but this "quick & dirty" hack is stable and reliable

Your complete frame should now look like this:


<?php
/* Generated by neoan3-cli */

namespace Neoan3\Frame;

use Neoan3\Core\Serve;

class VuePhp extends Serve
{
    function __construct()
    {
        parent::__construct();
        if($_SERVER['HTTP_HOST'] == 'localhost'){
            $this->includeJs(base . 'node_modules/vue/dist/vue.js');
        } else {
            $this->includeJs(base . 'node_modules/vue/dist/vue.min.js');
        }
    }
   
    function output($params = [])
    {
        $this->js .= 'new Vue({el:"#root"});';
        $this->main = '<div id="root">' . $this->main . '</div>';
        parent::output($params);
    }
}

What we are still missing is a nice way to integrate/load our custom vue components. We will set it up in a way that divides view (template) and js as we want to allow for dynamically changing the templates. Additionally, we will create the possibility to use component-based css (optional). To do so, we are going to provide routes with a new function called "vueComponents" to be placed in our frame:

function vueComponents($components, $params = []){
    // ensure that at least "base" is available
    $params['base'] = base;

    // iterate through provided component names
    foreach ($components as $component){
        $path = path . '/component/' . $component . '/' . $component  . '.ce.';

        // if template exists, write template to footer
        if(file_exists($path . $this->viewExt)){
            $this->footer .= '<template id="' . $component . '">' .
            $this->fileContent($path . $this->viewExt, $params) . '</template>';
        }

        // if js exists, write to js stream
        if(file_exists($path . 'js')){
            $this->js .= $this->fileContent($path . 'js', $params);
        }

        // if stylesheet exists, write to style stream 
        if(file_exists($path . $this->styleExt)){
            $this->style .= $this->fileContent($path . $this->styleExt, $params);
        }
    }
    return $this;
}

This is probable a little confusing. But our plan is to make custom elements vue components that we can load into endpoints with this function.

3. create cli-templates

The neoan3 cli-tool generates route components per default to be used with the Unicore. For our setup, we want to directly extend the frame rather than using the Unicore layer. Additionally, we want to have a handy boilerplate for our vue components. To achieve both, we will make use of the template capability of the cli tool. The cli tool respects such templates if they are defined in a folder "_template" in our neoan3 app. After creating this folder, we want to create 3 files:

  • ce.html
  • ce.js
  • route.php

With the following content:

ce.html

<div>{{name}}</div>

ce.js

Vue.component('{{name}}', {
    template: document.querySelector('#{{name}}')
});

route.php

<?php

namespace Neoan3\Components;

use Neoan3\Frame\VuePhp;

class {{name}} extends VuePhp {

    private $loadedComponents = [];

    function init(){

        $this->hook('main', '{{name}}')
            ->vueComponents($this->loadedComponents)
            ->output();
    }
}

What does this do? From now on, whenever we create a new custom element it will generate our vue component boilerplate. And whenever we create a new route component it will generate our setup intended to use these components.

How to use

Let's try it out. We assume a new endpoint called "home":

neoan3 new component home and chose "route component" using our frame.

Now we generate a new vue component called "login":

neoan3 new component login and chose "custom element"

Next, we open up "component/home/Home.ctrl.php" and add "login" to the array $loadedComponents. (note: in case sensitive environments, please be aware that you additionally have to change the second parameter of "->hook" to start with a lower case letter).

Now we open "component/home/home.view.html" and write the tag "login"

<login></login>

Visiting the endpoint /home, you should now see the string "login". This is the content of "component/login/login.ce.html" which is used as a template by "component/login/login.ce.js": Hack away!

image

Stop learning what you think is relevant

Still learning react, laravel & co? You better plan ahead!

image

How to use JWT in the neoan3 PHP framework

Many things have changed since I last addressed implementing JWT & stateless authentication & authorization.

image

Rapidly build your own stateless REST-API with neoan3

One of the most common tasks for a web-developer is interacting with an authenticated backend. While a plethora of possibilities are available, the way neoan3 handles things is not only convenient, but also fast and reliable.

image

Generating Phaser Game assets: Planet spritesheet generator

Ever needed to automate a process and all of a sudden you built a tool?

image

Do you even write?

Using the blua.blue webhook in order to track your writing.

Install PHP 8 on Ubuntu

PHP8 has finally been released and it is FAAAAST! Time to update.

image

6 Technologies to look at in 2021

2020 wasn't the best year humans can look back to. but what does 2021 bring for coders?

image

CSS Grid or CSS framework - are they really exclusive?

Grid-based or framework - there are many articles about this choice. But why is that even a thing?

image

Scaffolding REST APIs with JWT authentication

Ever had the need for your own backend while developing your web-app?

image

What is composer?

Composer has become PHP's package & dependency manager. Why you should use it.

image

MySQL: ERROR1364 fix

The painful realization of why people use containers.

image

Cyber wars: Defending your server

Maintaining your own server can be a thrill. High security standards can protect you from data leakage, injection attacks and DDoS attempts. But what about adaptive brute force?

Git: globally change GitHub-remotes from git@ to https

Does your IDE or composer set remote repositories to ssh rather than https? Or are repositories you are using set up that way? You are not alone. Let's fix it once and for all!

VueJS & neoan3: a love story.

Setting up neoan3 to play nice with Vue isn't hard. Here is how the two frameworks are combined to support fast, dynamic and rapid development.

image

MySQL in PHP - how to deal with databases

How I handle MYSQL database transactions in PHP

Install PHP 7.4 on Ubuntu

Finally PHP 7.4 is out! You have read about the new features, you have followed externals, you have gathered ideas on how new capabilities will save time. Let's get it running.

How to install global npm packages without sudo on Ubuntu

Running npm on a server can be painful. Privileges are there for a reason, and so is sudo. Running npm with sudo is not the solution.

image

Static content pages - still the fastest web-experience

Tutorial: How to utilize blua.blue to generate static content for your website.

image

Cross publishing to dev.to

How to publish your content to dev.to from blua.blue - hopefully

The Uselessness of Pre-Assessment

After almost two decades in the industry, new jobs will still ask you for "assessment tests". A little rant...

image

SEO strategies for blua.blue

How to get your content listed where you want it to.

image

How to Build an Express App in Node That Reads From a Headless CMS

A headless CMS lets you design your own front-end, sometimes your own back-end. Let's set up a small application to get us started. Beginner friendly. Approx. 20 min. to reproduce / follow along

Transformer - falling in love with PHP's magic methods all over again

PHP's magic functions have been around for a long time. But there were always good reasons to avoid them. Transformer is a practical and reliable way to make use of the most common operations we program: CRUD operations.

image

Help us document neoan3

Over 4000 brave developers are exploring the framework on their own.

image

When politics kill innovation

How misunderstood diversity killed the PHP Central Europe Conference for good.

image

blua.blue PHP SDK

Create your own blog.

image

dev.to plugin for headless CMS blua.blue (part 2)

A solution to supplying plugins to blua.blue