VueJS, el framework JavaScript que te hace la vida más fácil

Bueno, si es Vue, dos veces bueno. Seguro que ya habrás oído acerca de VueJS, uno de los framework JavaScript más populares en la actualidad, el cual nos permite construir interfaces de usuario de una forma muy fácil. Tanto es así que su curva de aprendizaje es prácticamente nula si ya conoces al detalle JavaScript y sabes trabajar con callbacks, promesas y objetos.

¿Qué es VueJS?

Vue ya tiene una dilatada historia. En 2014 Evan You acababa de terminar su etapa en Google como desarrollador y entre otros proyectos también había trabajado en Angular. Su experiencia le permitió crear su propia biblioteca personal que posteriormente liberó al público. Fue precisamente la comunidad quien hizo crecer el proyecto hasta convertirse en el potente y ligero framework que es en nuestros días.

Seguramente te estás preguntando quien usa VueJS. Empresas como Xiaomi, Alibaba o Gitlab son algunos de sus grandes exponentes pero si preguntas en tu entorno seguro que alguien está trabajando desde hace tiempo con este framework.

Angular y React están muy bien pero VueJS no pretende seguirles la estela. Desarrollado desde cero, una de sus características más importantes es el trabajo con componentes. Un componente en Vue, en términos generales, es un código encapsulado que se utiliza como un elemento reutilizable. Los componentes están diseñados bajo el patrón MVVM y dentro de un componente podremos encontrar desde etiquetas HTML, estilos de CSS a código JavaScript. Los componentes nos permiten desarrollar proyectos modularizados y fáciles de escalar, si nosotros así lo deseamos podemos reemplazar un componente por otro de una forma muy sencilla, como en un juego de bloques. Es decir, a partir de la librería central es posible agregar otras que la complementen.

Características

Tal como comentábamos VueJS es un framework pensado para hacer las cosas más simples. Pero si todavía tienes dudas para “adentrarte en sus dominios” quizá un repaso por sus características generales te ayude a decidirte.

  1. Un framework progresivo. Podemos incluir las partes que necesitamos además de la librería core y luego incluir otras librerías como si fueran módulos separados. Esto permite añadir funcionalidad a medida que lo necesitemos. El core principal de VueJS está formado por una librería encargada de renderizar vistas en el navegador.
  2. Intuitivo, moderno y fácil de usar. VueJS no ha reinventado la rueda pero desde sus comienzos su premisa es que sea tan fácil y simple de usar que la comunidad pueda usarlo para sus proyectos sin apenas curva de aprendizaje.
  3. Un ecosistema muy variado que cubre todo lo necesario. VueJS tiene a su alrededor una serie de herramientas que ayudan a conseguir que el desarrollador sepa en todo momento qué está haciendo y cómo lo está haciendo. Desde un interface de línea de comandos (CLI) a una plantilla base que podemos invocar mediante la herramienta vue-cli disponible en los repositorios npm, pasando por un largo etcétera de módulos y complementos.
  4. Una comunidad muy activa. Revisiones constantes, buena documentación, comunidad dispuesta a echar una mano cuando estás atascado. Un lujo.
  5. Todo el código de un componente se encuentra en un único fichero. Los componentes guardan todo lo necesario en ficheros con extensión .vue. Estos ficheros contienen de manera ordenada todo el HTML, el CSS y el JavaScript necesario.

Primeros pasos

Si queremos hacer uso de Vue no será necesario instalar absolutamente nada en nuestra computadora, si así lo deseamos podemos utilizar este framework mediante un CDN.

Vue.js es un framework progresivo, eso quiere decir que podemos usarlo para algo múy básico, igual que antes se usaba jQuery para cosas sencillas, o para algo más complejo como el desarrollo de una SPA, o para Server-Rendering. Siempre con un rendimiento y experiencia de desarrollo muy buena.

Si queremos hacer un uso muy básico de Vue y crear una aplicación muy sencilla, no falta que utilicemos Webpack, ni necesitamos instalar transpilers ni nada. Simplemente con importar la librería en el HTML (Desde un CDN como cdnjs o unkpg) ya podemos utilizar Vue.

La forma más fácil de probar Vue.js es usando el ejemplo Hola Mundo en JSFiddle. Siéntase libre de abrirlo en otra pestaña y seguirlo mientras analizamos algunos ejemplos básicos. O puede crear un archivo index.html e incluir Vue con alguna de estas opciones:

 

Hola Mundo

Para comenzar a dar nuestros primeros pasos con VUE una ejercicio simple es programar nuestro primer Hola Mundo.

Como podemos ver como el id “hello-world-app” actúa como elemento identificador donde luego nuestro script retorna el mensaje “Hola Mundo” mediante la función contenida en el objeto Vue.

El siguiente paso es crear el objeto Vue, en la propiedad «el» definimos el nombre del elemento principal donde va a actuar Vue y en data definimos las propiedades de la clase como la propiedad msg con la cual podremos trabajar luego en las vistas.

<!DOCTYPE html>
<html lang="en">
  <meta>
    <meta charset="UTF-8">
    <title>Hello World in Vue.js</title>
  </meta>

  <body>
	
    <div id="hello-world-app">
      <h1>{{ msg }}</h1>
    </div>

    <script
      src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js">
    </script>

    <script>
      new Vue({
        el: "#hello-world-app",
        data() {
          return {
            msg: "Hola Mundo"
          }
        }
      });
    </script>

  </body>
</html>

Tres en raya

Ahora vamos con otro ejemplo, un sencillo juego de tres en raya. El código fuente puede descargarse desde el siguiente repositorio de GitHub. Para comenzar usaremos vue-cli, una herramienta de interfaz de línea de comandos que nos servirá para crear la estructura básica del programa.

Ahora vamos con otro ejemplo, un sencillo juego de tres en raya. Para comenzar usaremos vue-cli, una herramienta de interfaz de línea de comandos que nos servirá para crear la estructura básica del programa.

npm install -g vue-cli

Ahora que vue-cli, ejecute los siguientes comandos en el terminal para que vue-cli andamie la estructura del proyecto por usted:

vue init webpack-simple vue-tic-tac-toe

Aquí, vue-tic-tac-toe es el nombre del proyecto, en el cual vue-cli se iniciará. Webpack-simple es una plantilla que incluye tanto Webpack como vue-loader. El siguiente paso será instalar las dependencias.

cd vue-tic-tac-toe
npm install

Cree una carpeta de componentes en el directorio src presente en la raíz. Contendrá todos nuestros componentes. Ahora que todo está listo, ejecute este comando para ver esta aplicación en el navegador:

npm run dev

Este comando cargará http:// localhost:8080/ en el navegador. Cada cambio que realice en su código se reflejará en el navegador incluso sin actualizar la página. Abra App.vue en su editor de código y elimine todas las cosas innecesarias presentes en la plantilla y la etiqueta del script. Nuestro archivo HTML será muy básico, sustituiremos su estructura por lo siguiente:

<script type="text/x-template" id="grid">
  <div class="grid">
    <div class="row" v-for="row in rows">
      <div class="column" v-for="column in row">
        {{column}}
      </div>
    </div>
  </div>
</script>

La cuadrícula está formada por tres filas y columnas formando una matriz en dos dimensiones en donde se representarán los datos. Será nuestro tablero de juego en donde “O” y “X” serán usadas como las fichas que representarán a cada jugador.

Una vez definida la estructura nos queda definir su aspecto editando nuestra hoja de estilo CSS.

.row {
  clear: both;
}
.column {
  border: 1px solid #000;
  width: 50px;
  height: 35px;
  float: left;
  text-align: center;
  padding-top: 15px;
}

.status {
  clear: both;
}

Ahora ya solo queda comenzar a trabajar en nuestro código JavaScript. Tenemos que crear y definir nuestra cuadrícula como un componente, y luego crear nuestra aplicación Vue que se dibujará en el div #app.

var Grid = Vue.component('grid', {
  template: '#grid'
});

Sin embargo, necesitaremos establecer nuestros datos iniciales para el componente: las filas y columnas que representa la plantilla:

data: function() {
    return {
      rows: [
        ['', '', ''],
        ['', '', ''],
        ['', '', '']
      ]
    };
  }

Aquí las filas (rows) son una matriz 2D, una matriz de matrices, cada matriz representa una fila y cada valor que representa una columna en esa fila, y están inicializadas todas en blanco y sin reproducir.

Ahora vamos con nuestra aplicación.

var App = new Vue({
  el: '#app',
  components: {
    Grid
  },
  render: function(createElement) {
    return createElement(Grid);
  }
});

Necesitamos que cada jugador pueda seleccionar un espacio. Si espacio está vacío añadiremos una “X” o “O” para marcar nuestra jugada en función del turno del jugador activo en ese momento.

En principio esto podría ser algo así:

 data: function() {
    return {
      rows: [
        ['', '', ''],
        ['', '', ''],
        ['', '', '']
      ],
      next: 'x'
    };
  },

Pero así solo acabamos de agregar el atributo con un valor predeterminado de “x” a los datos de nuestros componentes. Necesitamos agregar un método que permita cambiar de un valor a otro en cada jugada.

methods: {
  tap: function(e) {
    if (e.target.innerText == '') {
      e.target.innerText = this.next;
      this.next = (this.next == 'x' ? 'o' : 'x');
    }
  }
}

Por lo tanto, esto solo funciona si el espacio está libre, establece el espacio y luego define qué jugador es el siguiente. Y con un último paso ya lo tenemos. Cuando se produzca un evento click el programa sabrá cuando cada jugador tiene su turno.

<div class="column" v-for="column in row" v-on:click="tap">
  {{column}}
</div>

Ya tenemos la lógica pero todavía no podemos hacer mucho ya que todavía no estamos actualizando nuestros datos en función de la jugada de cada usuario, solo estamos actualizando la capa visual y necesitamos actualizar nuestra matriz de datos y que eso se refleje en la interfaz de usuario, que es la forma correcta de hacer las cosas. ;)

<script type="text/x-template" id="grid">
  <div class="grid">
    <div class="row" v-for="(row, row_index) in rows">
      <div class="column" v-for="(column, column_index) in row" v-on:click="tap" v-bind:data-row="row_index" v-bind:data-column="column_index">
        {{column}}
      </div>
    </div>
  </div>
</script>

Específicamente, hacemos un seguimiento del índice de fila y columna en nuestro bucle de matriz bidimensional, y luego lo vinculamos como variables de datos de fila y columna para referenciar cuando se reproduce un espacio.

A nuestro método tap ahora:

tap: function(e) {
  if (e.target.innerText == '') {
    let rows = this.rows;
    rows[e.target.attributes['data-row'].value][e.target.attributes['data-column'].value] = this.next;
    this.rows = rows.slice(0);
    this.next = (this.next == 'x' ? 'o' : 'x');
  }
}

Aquí estamos tomando las filas de datos, luego actualizando el valor de nuestra columna, usando los enlaces de fila de datos y columna de datos presentes en el elemento para encontrar la ubicación correcta en la matriz.

Ya solo queda decidir quién es el ganador, debemos verificar cada fila para ver tres valores coincidentes, cada columna para tres valores coincidentes y las dos rutas diagonales para tres valores coincidentes. Si alguno de esos es cierto, ¡tenemos un ganador! Podemos reducir esto a lo siguiente:

checkWinner: function() {
  return (
    this.checkValues(this.rows[0]) ||
    this.checkValues(this.rows[1]) ||
    this.checkValues(this.rows[2]) ||
    this.checkValues([this.rows[0][0], this.rows[1][0], this.rows[2][0]]) ||
    this.checkValues([this.rows[0][1], this.rows[1][1], this.rows[2][1]]) ||
    this.checkValues([this.rows[0][2], this.rows[1][2], this.rows[2][2]]) ||
    this.checkValues([this.rows[0][0], this.rows[1][1], this.rows[2][2]]) ||
    this.checkValues([this.rows[0][2], this.rows[1][1], this.rows[2][0]]));
},
checkValues: function(values) {
  return (values[0] != '' && values[1] != '' && values[2] != '' && (values[0] === values[1]) && (values[1] === values[2]));
}

Con nuestra lógica para definir el ganador ya solo es momento de conectarla. Para ello agregaremos una propiedad adicional, terminada, a nuestros datos:

data: function() {
  return {
    rows: [
      ['', '', ''],
      ['', '', ''],
      ['', '', '']
    ],
    next: 'x',
    finished: false
  };
},

Tenemos que asegurarnos que el juego no pueda continuar una vez que hayamos terminado, en la parte superior del método tab añadiremos la siguiente condición:

tap: function(e) {
  if (!this.finished && e.target.innerText == '') {

Por último, en términos de lógica, sólo necesitamos modificar el final de nuestro método tap:

if (this.checkWinner()) {
  this.finished = true;
} else {
  this.next = (this.next == 'x' ? 'o' : 'x');
}

Así, si no hemos encontrado ganador, el programa continuará el juego hasta alcanzar la jugada que defina al ganador, terminando el juego.

El último toque del programa es anunciar al ganador o si no lo hay que jugador tiene su turno. Esto podemos hacerlo añadiendo una par de líneas adicionales en nuestra plantilla html.

<div class="status">
  <span v-if="finished">Finished! {{next}} wins!</span>
  <span v-else>Next go: {{next}}</span>
</div>

Y con esto terminamos una versión básica del juegos tres en raya con muy poca edición de código, algo de HTML y CSS. ¡Todo gracias a Vue.JS!

Conclusión

Por supuesto estos son solo unos ejemplos. No es lo mismo trabajar solo en un proyecto personal que trabajar con un equipo de veinte desarrolladores. Sin embargo es evidente que con VUE todo está en su sitio, sin fricciones entre el librerías y componentes. Y si ya conoces JavaScript resulta muy fácil leer el código y entenderlo. Casi no notarás el cambio. Particularmente, me parece un paso muy natural si vienes de trabajar con jQuery. Pero como para gustos colores, puede que prefieras seguir trabajando con otros framework más conocidos como Angular o React pero si te encuentras cómodo con su filosofía y conceptos estoy seguro que te enganchará. y que te encuentres tan bien desarrollando con VueJS que quizá ya no quieras cambiar.