Vue.js con Liferay DXP

17 de julio de 2017

Vue.js (vuejs.org) es un framework de JavaScript para construir interfaces de usuario. El creador de Vue.js trabajo en el equipo de AngularJs, por lo que este framework tiene muchas similitudes con AngularJs. Es una pequeña biblioteca de funciones y gracias a su diseño es muy fácil de integrar con otros frameworks. Considero que es una Buena opción para poder desarrollar portlets para Liferay

Hello world!

La primera cosa que hay que hacer es importar la librería,

<script src="https://unpkg.com/vue"></script>

Como estoy jugando con los decorados de Liferay, la he importado en mi propio theme. Pero tú puedes importarla en tu portlet, para ello añade las siguientes líneas:

<script>
    define._amd = define.amd;
    define.amd = false;
</script>

<script src="https://unpkg.com/vue"></script>

<script>
    define.amd = define._amd;
</script>

Si necesitas más información puedes leer sobre ello https://dev.liferay.com/es/develop/tutorials/-/knowledge_base/7-0/using-external-libraries.

Ahora puedes copiar estas dos secciones (el código html y javascript) en tu fichero view.jsp.

<div id="app">
  {{ message }}
</div>

<script>
  var app = new Vue({
    el: '#app',
    data: {
      message: 'Hello world!'
    }
  });
</script>

Puedes pensar en ello de esta forma sencilla: la aplicación Vue.js (código JavaScript) y el lugar donde va a ser desplegado (código html).

Date cuenta que la aplicación tiene la propiedad el con el valor #app, esto significa que debemos tener un elemento en nuestro html con el identificador app.

En la aplicación, tenemos una sección data, cada elemento que se declara aquí va estar accesible desde cualquier lugar de nuestra aplicación. Como en nuestra plantilla hemos puesto {{message}}, _Vue.j_s renderizará Hello World!. La misma magia que tiene AngularJs.

El resultado es el que esperas:

Filtrando una lista de países

Hemos visto lo básico de Vue.js, ahora vamos a ver algo más complejo.

He creado un método que devuelve una lista de códigos internacionales de países. Puedes ver el código en el repositorio, pero para este artículo, solo necesitas saber que esta es la línea a incluir en el código:

<portlet:resourceURL id="/countries" var="countriesURL" />

Como en AngularJs hay directivas que puedes usar en tus plantillas, en Vue.js todas las directivas empiezan por “v-“. Si queremos iterar sobre una lista de elementos, tenemos la directiva v-for.

<ul>
     <li v-for="country in countries">
         <span>{{country.name}}</span>
         <span>{{country.code}}</span>
     </li>
 </ul>

Como has imaginado Vue.js itera sobre la variable contries y va creando un elemento li por cada país. ¿Dónde definimos la variable countries?

El lugar para ello es en la sección data.

data: {
    message: 'Hello World!',
    countries: []
}

Hemos declarado un array vacío, la idea es rellenarlo mediate una llamada AJAX.

created: function () {
    this.fetchData();
}

methods: {
    fetchData: function () {
        $.getJSON("<%= countriesURL%>", function(result){
            this.countries = result;
        }.bind(this));
    }
}

Para ello hemos declarado la función fechData dentro de la sección methods, todas las funciones definidas aquí, pueden ser invocadas en toda la aplicación Vue.js. Esto significa que podemos insertar un botón y llamar a nuestra función cada vez que lo pulsamos.

Como queremos que los datos esten accesibles cuando la aplicación ha sido creada, usamos la sección created.

Debido a su diseño, Vue.js no tiene por defecto la opción de crear peticiones AJAX. Para ello podemos usar _Vue Resourc_e (https://github.com/pagekit/vue-resource), lo que implica cargar más librerías. Por otro lado ya que Liferay carga una versión de jQuery, he decido usarla.

Añadir un filtro

Ahora vamos a añadir un filtro,

<input type="text" v-model="keyword" placeholder="Search Title..."/>

Una caja de texto con la directiva v-model. Esta directiva crea un doble binding para la variable keyword. Esto significa que cada vez que escribimos en la caja de texto, el valor de la variable cambia. Usaremos esta variable para filtrar nuestra lista de países.

<ul>
    <li v-for="country in filteredList">
        <span>{{country.name}}</span>
        <span>{{country.code}}</span>
    </li>    
</ul>

La nueva lista se crea en la sección computed, esta es una sección que se ejecuta cada vez que una variable cambia su valor.

computed: {
             filteredList: function() {
                 return this.countries.filter(function(element) {
                     return element.name.toLowerCase().includes(this.keyword.toLowerCase());
                 });
             }
         }

El resultado es:

Todo el código está disponible en el repositorio: https://git.mimacom.com/users/cagr/repos/article-vue.js/browse

Sobre el autor: Carlos García
Comments
Únete a nosotros