Screencast #05 - Using Vue.js in a Pagekit extension

Using Vue.js in a Pagekit extension

To build the Pagekit admin area, we explored the vast landscape of JavaScript frameworks. A rather fresh candidate turned out to be the right choice for us: Vue.js, a library with a simple but powerful API. We fell in love with it and hope you will as well.

When building your own screens for the admin area, you can use any library you are used to. But as Pagekit comes with Vue.js included, it makes sense to look into it and see if it's the right choice for you as well.

In this post, we will be introducing the basic concepts of working with Vue.js inside Pagekit. The completed example extension can be found on Github.

1. Passing data to JavaScript

In the past posts we have seen how data can be accessed in PHP controllers. To use this data in JavaScript, use the $data keyword to pass PHP arrays to the view renderer. Pagekit will automatically convert this to a JSON representation and render it in the head section of the generated HTML.

// packages/pagekit/todo/src/Controller/TodoController.php

// ...

public function indexAction()
{
    $module = App::module('todo');

    return [
        '$view' => [
            'name' => 'todo:views/admin/index.php'
        ],
        '$data' => $module->config
    ];

}

This will render the following in your <head> section.

<script>
    var $data = {
        "entries": [{"message":"Buy milk","done":false},{"message":"Drink coffee","done":true}]
    };
</script>

2. Combine view and model

The ViewModel is a Vue instance that syncs the data from your model with the interface of your view. This is called reactivity and is one of the key features of Vue. Used correctly, this helps to keep your JavaScript components small and readable.

You can attach the Vue instance to a DOM element: el: '#todo'. The model will be whatever you pass to the data parameter. To use data from Pagekit, take the global window.$data object that your view has rendered.

Any methods you create can be called from your template. We will create the template markup in the next step.

// packages/pagekit/todo/js/todo.js

$(function(){

    var vm = new Vue({

        el: '#todo',

        data: {
            entries: window.$data.config.entries,
        },

        methods: {

            add: function(e) {
                // ...
            },

            toggle: function(entry) {
                entry.done = !entry.done;
            },

            remove: function(entry) {
                this.entries.$remove(entry);
            },

            save: function() {
                // ...
            }

        }

    });

});

2. Markup for Vue

From PHP, we still render the view file views/admin/index.php. In here, we include the required JavaScript files. To make Vue available in your script, add a dependency to vue as a third parameter.

<?php $view->script('todo', 'todo:js/todo.js', 'vue') ?>

In your HTML, include the DOM element that the Vue instance is looking for: <div id="todo"></div>. Inside the element, you can use Vue directives. Directives are certain keywords that tell Vue what to do with the element.

<p v-if="entry.done">This will be displayed if the item has been done.</p>

With @click you can bind to the click event and call methods of your view model.

To output values from your model, you can use curly braces: {{ entry.message }}. Pagekit provides a trans filter which will replace the string with a translated alternative if there is one present for the selected locale.

{{ 'Save' | trans }}

This is how a simple view might look like.

<!-- packages/pagekit/todo/views/admin/index.php -->

<?php $view->script('todo', 'todo:js/todo.js', 'vue') ?>

<div id="todo">

    <button @click="save()">{{ 'Save' | trans }}</button>

    <ul>
        <li v-for="entry in entries">
            {{ entry.message }}

            <button @click="click: toggle(entry)">{{ entry.done ? 'Undo' : 'Do' }}</button>
        </li>
    </ul>

</div>

3. The completed example

In the completed example, we have implemented the actual saving to the backend and cleaned up the source code. It combines all previous steps where we described how to create a simple Todo extension. The result is available on Github for you to fiddle around with.

Todo Example on Github

Learn more about Vue

Vue.js is a powerful library that makes it easy to build reactive web interfaces. To learn more, checkout the official guide. We can also highly recommend the Laracasts videos on Vue.js. Both are great places for an overview of what Vue can do, either in written form or as videos.

Feedback and comments

Even though we have reached the end of the Todo example, this is not the last screencast you will see. As some of you requested a look at users and permissions, we will talk about that in the next video. For more ideas, write a comment below and join us in our developer chat.

Here is a short list of all existing screencasts:

Florian
Posted by Florian
{{ message }}

{{ 'Comments are closed.' | trans }}