Skip to content
A Vue.js helper for create Vue app in Yii2 without webpack or similar
PHP JavaScript CSS
Branch: master
Clone or download
Latest commit ae9e968 Aug 17, 2019

README.md

Vue.js helper for Yii2

This is a component that helps to create Vue.js app without usign webpack or similar.

All assets (js, css and templates) are injected directly in the html and this components provides functionalities to split the code (js, css and templates) and to load parameters from html root element.

Two default packages are embedded with this component: Axios and Moment. There is an example that shows how use both in the code.

Installation

The preferred way to install this extension is through composer.

Either run

php composer.phar require --prefer-dist fabriziocaldarelli/yii2-vueapp "@dev"

or add

"fabriziocaldarelli/yii2-vuejsapp": "@dev"

to the require section of your composer.json file.

How it works

This component injects js, css and tpl (php or html) files into the returned html.

These files are read starting from same folder of action view file, appending vueapp/actionName/js or vueapp/actionName/css or vueapp/actionName/tpl

VueApp::begin mainly supports three parameters:

  • id: vue app html tag id selector;
  • propsData: widget uses this element to pass data from html/php to js script;
  • packages: list of packages that should be loaded into js vue script

Pay attention: propsData keys have the same name (and same case) in php and in js file.

Usage

1) The view file

Inside the view, call VueApp widget:

<?php
use \sfmobile\vueapp\VueApp;

/*
- Css files are automatically loaded from vueapp/test/css/
- Template files are automatically loaded from vueapp/test/tpl/
- Js files are automatically loaded from vueapp/test/css/
- Passing packages parameter we require Axios and Moment package

To pass data from php/html to js vue app we defined propsApp attribute data in VueApp configuration and the we fill in html converting from camel case to dash
*/

VueApp::begin([
    'id' => 'vueAppTest',
    'propsData' => [
        'kParam1' => 'value_1',
        'kParam2' => 'value_2',
        'kParam3' => 'value_3',
    ],
    'packages' => [VueApp::PKG_AXIOS, VueApp::PKG_MOMENT]
]);
?>
    kParam1: {{ propsApp.kParam1 }}
    <br />
    kParam2: {{ propsApp.kParam2 }}
    <br />
    kParam3: {{ propsApp.kParam3 }}
    <br />
    clock datetime: {{ clock_datetime | formatDateTime('DD/MM/YYYY HH:mm') }}

<?php VueApp::end(); ?>

The most important parameter is packages that loads embedded packages such as Axios and Moment.

2) The Vue app js files

Starting from view path folder, js files for app and components are in vueapp/test/js/actionName/ .

For example, the path for main vue app js could be vueapp/test/js/test.js

var vueAppTest = new Vue({
    el: '#vueAppTest',
    data: {

        /**
         * propsApp is used to collect attribute related to root container element.
         * This is the suggested way to pass data from php to js vue app.
         * All parameter are converted from dash to camel case (html k-param-1 become kParam1)
         */
        propsApp: {
            kParam1: null,
            kParam2: null,
            kParam3: null,
        },

        clock_datetime: null
    },

    filters: {
        formatDateTime: function (value, format) {
            return value ? moment(value).format(format) : null
        }
    },

    mounted() {
        this.readPropsApp();

        this.loadAtomicClock();
    },

    methods: {

        readPropsApp: function () {
            for (var k in this.propsApp) {
                var attr = k.replace(/[A-Z|0-9]/g, m => "-" + m.toLowerCase());
                console.log(k, attr);
                if (this.$el.attributes[attr] != undefined) {
                    this.propsApp[k] = this.$el.attributes[attr].value;
                }
            }
        },

        loadAtomicClock: function () {

            var self = this;

            axios
                .get('http://worldtimeapi.org/api/ip')
                .then(function (response) {
                    console.log(response);
                    self.clock_datetime = response.data.datetime;
                })
                .catch(error => console.log(error));
        },

    }
})

3) The Vue app css files

Starting from view path folder, css files for app and components are in vueapp/test/css/actionName/ .

For example, the path for main vue app css could be vueapp/test/css/test.css

[v-cloak] {
    display: none
}

Tips & Tricks

1. Pass data from html/php to js

To pass data from html/php to js vue app, I used an attribute called propsApp, whithin are defined attributes passed in html root element.

For example, html root element "vueAppTest":

<div id="vueAppTest" v-cloak
    k-param-1="value_1"
    k-param-2="value_2"
    k-param-3="value_3"
>
...
</div>

all parameters defined in data.propsApp are readed from html when app is mounted (calling readPropsApp method):

var vueAppTest = new Vue({
    el: '#vueAppTest',
    data: {

        /**
         * propsApp is used to collect attribute related to root container element.
         * This is the suggested way to pass data from php to js vue app.
         * All parameter are converted from dash to camel case (html k-param-1 become kParam1)
         */
        propsApp: {
            kParam1: null,
            kParam2: null,
            kParam3: null,
        },

    },

    mounted() {
        this.readPropsApp();
    },

    methods: {

        readPropsApp: function () {
            for (var k in this.propsApp) {
                var attr = k.replace(/[A-Z|0-9]/g, m => "-" + m.toLowerCase());
                console.log(k, attr);
                if (this.$el.attributes[attr] != undefined) {
                    this.propsApp[k] = this.$el.attributes[attr].value;
                }
            }
        },
    }
}

2. Component registration

JS files loading order is important when the app js file depends from other js files.

So, I suggest to prefix all component files with '_' or suffix with '.component.' in order to load component js files firstly.

You can’t perform that action at this time.