Operaciones en matrices con Python – Creando la clase Base

matriz

Operaciones en matrices con Python

Hola a todos, luego de un tiempo sin escribir aquí les traigo esta entrada, la cual espero los ayude a entender este tema tan recurrente, como es el realizar operaciones en matrices con Python. En esta entrada veremos que es una matriz, y crearemos la clase que nos servirá de base para realizar las operaciones en las pr

Hasta el momento las entradas de esta serie han sido las siguientes:

Creando la clase Base

Suma de matrices

Producto por un escalar

Producto de matrices (Pendiente)

Transpuesta (Pendiente)

¿Qué es una matriz?

Las matrices son arreglos k-dimensionales donde se almacenan valores que pueden ser accedidos por indices. En las matemáticas, se conocen desde el año 200 a.C. y siempre han estado vinculadas al estudio de sistemas de ecuaciones. Toda una rama de esta ciencia está dedicada al estudio de matrices y durante mucho tiempo han sido ampliamente invetigadas.

Probablemente el caso más conocido de matriz se tenga cuando k = 2 (bidimensional), con n filas y m columnas, básicamente lo que se entiende por una tabla. A continuación podemos observar una matriz cuadrada donde n = m = 3.

operaciones en matrices con python

operaciones en matrices con python

Entre las operaciones más comunes en matrices se encuentran la suma, la resta y la multiplicación. Para comenzar el estudio de dichas operaciones, primero crearemos una clase matrix que represente a la estructura de datos y que en su momento servirá como contendor para diferentes funciones aplicadas sobre matrices.

#!/usr/bin/python
# -*- coding: utf-8 -*-
# author: Gabriel Cueto <TheMushr00m - @Mushr00m_Dev>


class Matrix:
    _n = 0
    _m = 0
    _elems = None

    def __init__(self, n, m):
        """Inicializa la matriz con valor 0 en cada posición"""
        self._n = n
        self._m = m
        self._elems = []
        for i in range(self._n):
            self._elems.append([])
            for j in range(self._m):
                self._elems[i].append(0)

    def define_elem(self, i, j, v):
        """ Sobreescribe el valor de una celda """
        self._elems[i][j] = v

    def show_matrix(self):
        """ Imprime los valores almacenados en la matriz """
        for i in range(self._n):
            for j in range(self._m):
                # Imprime de una forma elegante la matriz
                print("| {0} ".format(self.get_value_of_position(i, j)), sep=',', end='')
            print('|\n')

    def get_cols(self):
        """ Devuelve el número de columnas en la matriz """
        return self._m

    def get_rows(self):
        """ Devuelve el número de filas en la matriz """
        return self._n

    def get_value_of_position(self, i, j):
        return self._elems[i][j]

    cols = property(fget=get_cols)
    rows = property(fget=get_rows)

Como podrás observar, la matriz se inicializa con valor 0 en cada celda, y la modificación de estos valores tiene lugar mediante el método define_elem. Ahora es el momento de escribir el código para poder lograr nuestro objetivo, realizar operaciones en matrices. Esta de más decir, que los próximos métodos serán declarados como parte de la clase anterior.

Si deseas probar el código y visualizar como se genera la matriz, corre lo siguiente ya que tengas el código de la clase:

m = Matrix(3, 3)
m.show_matrix()

Espero el código de nuestra clase base haya quedado claro, si tienes alguna pregunta no dudes en hacerla en los comentarios, o mediante twitter.

Nuevamente te hago la invitación de que me sigas en mis redes, Twitter, Facebook, para que estes pendiente de nuevas entradas, charlas, proyectos, compartas contenido, etc.

Te pido una disculpa por si el código no se visualiza correctamente (sin identación), ya me encuentro trabajando en revisar esto, aunque creo que voy a enfocarme en el rediseño que estoy llevando a cabo para poder tenerlo pronto, sin embargo puedes encontrar todo el código en su repositorio de GitHub.

Gracias por leer la entrada, y no te pierdas las próximas donde realizaremos las operaciones con matrices. Saludos.

Estructura de Datos – Pilas en Python

Pila

Estructura de Datos: Pilas en Python

Hola a todos, primero quiero agradecer su apoyo al seguir el blog. Luego de unos días de descanso para poder pensar algunas cosas, aquí traigo un rápido ejemplo, del que me sugirieron escribir vía Twitter. El tema que vamos a revisar en esta ocasión, será el tema perteneciente a la asignatura de Estructuras de Datos: Pilas.

Para esto, los ejemplos que veremos serán llevados a cabo utilizando el lenguaje Python. Esto debido a que el objetivo de esta entrada es que el concepto quede claro para todos, y así pueda ser aplicado en cualquier lenguaje.

Pilas en Python¿Qué es una Pila?

Bien, una pila como estructura de datos, funciona exactamente cómo sucede en el mundo real en un conjunto de objetos superpuestos verticalmente. Imagina que eres estudiante, y estás buscando un objeto en tu mochila. Por más que mueves las cosas no logras encontrar lo que buscas, así que comienzas a sacar tus libros y los apilas, uno sobre otro. Con esto lograste ubicar el objeto que buscabas, paso siguiente, pones los libros de regreso en tu mochila, comenzando por el libro que se encuentra en el tope de la pila, y así hasta llegar al último. (Ya que confío en que eres ordenado).

Libros_apilados: Pilas en PythonSi analizamos un poco el ejemplo, podemos notar ciertas cosas, al agregar un nuevo elemento (un libro) a la pila, pasará a colocarse en el tope, ya que siempre en una pila, el último elemento en ingresar a la pila, será el tope de la misma. Mientras que para eliminar un elemento (guardar un libro) comenzaremos por el último en haber sido introducido a la pila (que se encuentra en el tope).

Esto es debido a que las pilas, son una estructura de datos del tipo LIFO (“Last In, First Out”), lo que nos dice que el último elemento en ingresar a la pila, será el primero en salir de ella. Espero el concepto haya quedado claro, de no ser así, tal vez con el siguiente ejemplo lo puedan comprender mejor.

Las operaciones distintivas de una pila son: pop(), para sacar (remover) el elemento en el tope de la pila y push() para empujar (añadir) un elemento en el tope. Cada vez que se realiza una operación push() la pila aumenta de tamaño y el tope se modifica siendo ahora el elemento añadido. En el caso de la operación pop() disminuye el tamaño de la pila, y el tope ahora será el elemento debajo del elemento a ser removido, generalmente esta operación devuelve el elemento removido. Otra operación que generalmente se implementa en una pila, es peek(), que devuelve el elemento que se encuentra como tope de la pila, sin removerlo.

Creando una pila con Python

class Stack:
elements = []

def __init__(self):
self.elements = []

def get_size(self):
return len(self.elements)

def push(self, x):
self.elements.append(x)

def pop(self):
return self.elements.pop()

def get_peek(self):
return self.elements[-1]

peek = property(fget=get_peek)
size = property(fget=get_size)


s = Stack()
s.push("a")
s.push("b")
s.push("c")
s.push("d")
s.push("e")
s.push("f")
s.push("h")

El código es algo simple, definimos una clase, la cual será nuestra Pila, que contiene un atributo elements, el cual será una lista vacía. Con __init__() establecemos la lista como vacía al crear una nueva instancia. Contiene un método get_size(), que retorna el tamaño de la pila, push() para añadir un elemento al tope de la pila, pop() para remover el elemento en el tope y devolverlo y get_peek(), que nos devuelve el elemento en el tope sin removerlo, en este caso utilizamos la expresión elements[-1], que es la forma de obtener el último elemento de una lista (recuerdan que en Python, una pila no es más que una lista).

Paso seguido creamos una instancia y añadimos algunos valores a nuestra pila, quedando de esta forma:

Pila recién creada: Pilas en PythonComo se observa, h es el elemento que se encuentra en el tope de la pila. Si ejecutamos las operaciones mencionadas anteriormente. get_size() devuelve el valor de 8, con get_peek() obténdremos “h”, y con pop() también obtendremos “h”, la diferencia es que ahora nuestra pila se encuentra de la siguiente forma.

Pila luego de Pop: Pilas en PythonSi observas, ahora el tope de la pila es “g”, y el tamaño actual es de 7.

Este ejemplo podría mejorarse un poco. Se podría añadir una validación para evitar que se intente hacer pop() si la lista se encuentra vacía, te invito a realizarlo a modo de práctica y lo expongas en los comentarios.

La pila es probablemente una de las estructuras de datos más utilizadas en el ámbito de la programación, y de la informática en general me atrevería a decir. Son utilizadas en ocasiones de manera inconsciente, cuando definimos algoritmos recursivos, dado que los lenguajes de programación implementan este mecanismo mediante una pila que almacena los llamados recursivos.

Y bien, es todo por ahora, espero haber sido lo suficientemente claro, y que los conceptos hayan quedado claros. Cualquier comentarios no dudes en escribirme, ya sea a mi cuenta de Twitter, en donde te invito a que me sigas, como en la FanPage de Facebook, la cual te invito a que le des Me gusta para que te mantengas al tanto de anuncios y nuevas entradas que iré publicando.

Saludos.

Técnicas de programación: Patrón memoize

Patrón Memoize

Hola a todos, bienvenidos a una nueva entrada de este blog, y en esta ocasión vengo a escribir sobre un tema que a muchos les será de utilidad. Conoceremos qué es el patrón memoize o de memorización con ayuda de nuestro buen amigo, el lenguaje Python en su versión 3.6.0.

¿Qué es el patrón memoize o de memorización?

El patrón memoize consiste en almacenar las soluciones calculadas previamente, para evitar que sean recalculadas, logrando con esto, reducir el tiempo computacional de nuestros algoritmos.

Este patrón es empleado en diversas técnicas de programación, entre ellas, la programación dinámica, ¿sencillo, no lo creen?

Creo que un ejemplo permitirá que esto quede más claro. Para ilustrar esto, escribiremos un decorador que siga este patrón, por lo tanto, almacenará las soluciones en un diccionario para ser reutilizadas al ser requeridas nuevamente.


#!/usr/bin/env python
# -*- coding: utf-8 -*-


def memoize(f):
memory = {}

def wrapper(n):
if n not in memory:
memory[n] = f(n)
return memory[n]
return wrapper

 

Como podemos observar, el código no debería resultar demasiado complejo. Es la definición de una función decorator. Si miramos detenidamente el código, observamos que la función memoize recibe un argumento f, que se trata de la función que será “decorada”.

Paso siguiente, se define un diccionario, el cual almacenará los valores que se vayan calculando en la función. Tenemos nuestra función de envoltura (wrapper), la cual recibe un argumento n, que se trata del valor que está siendo calculado.

Dentro de nuestra función de envoltura, se verifica que el elemento no se encuentra en nuestro diccionario, si la condición se cumple entonces lo añade al mismo, de lo contrario, simplemente retorna el elemento desde el diccionario. Y por último, devuelve la función de envoltura.

Poniendo en práctica nuestra función memoize

Un problema que aprovecha enormemente este patrón, es el conocido problema de encontrar el n-ésimo número de la sucesión de Fibonacci. Así que, primero vamos a crear nuestra función para lograr tal objetivo.


def fibonacci(n):
if n < 2:
return n
return fibonacci(n - 1) + fibonacci(n - 2)

 

Como podemos apreciar, estamos utilizando la versión recursiva de la función para realizar la operación. Con esto, podemos apreciar de mejor forma las ventajas del patrón memoize. En principio este algoritmo genera un árbol recursivo, el cual se halla plagado de subárboles que corresponden a casos resueltos en diferentes ramas, y por lo tanto, están siendo recalculados.  En la siguiente imagen podemos ver la explosión arbórea cuando n = 6.

qué es el patrón memoizePara evitar esta situación, podemos valernos de una solución de ramificación y poda, utilizando el decorador memoize que creamos previamente, evitando así cálculos innecesarios.


# Utilizando Memoize
@memoize
def fib_memoize(n):
if n < 2:
return n
return fib_memoize(n - 1) + fib_memoize(n - 2)

 

Lo sé, lo sé, seguro están pensando que no hay forma de comprobar que realmente esto funciona. Hagamos algo, modifiquemos un poco el código del decorador para que indique cuando una solución ha sido calculada previamente, con esto podremos apreciar que la memorización se está llevando a cabo.


# Decorador mejorado, para visualización
def memoize_debug(f):
memory = {}

def wrapper(n):
if n not in memory:
memory[n] = f(n)
else:
print("Result was previously calculated: {0}".format(n))
return memory[n]
return wrapper

 

De igual forma, vamos a modificar nuestra función fib_memoize para que utilice nuestro nuevo decorador.


@memoize_debug
def fib_memoize(n):
if n < 2:
return n
return fib_memoize(n - 1) + fib_memoize(n - 2)

 

Si realizamos la prueba de nuestra función, el resultado para n=6 será.

In[1]: fib_memoize(6)

Result was previously calculated: 1
Result was previously calculated: 2
Result was previously calculated: 3
Result was previously calculated: 4

Out[1]: 8

Les dejo el código en el repositorio en Github.

Por esta ocasión es todo, espero los conceptos hayan quedado claros, de lo contrario, no duden en escribir sus dudas en los comentarios. No olviden seguirme en mis redes, ya sea twitter, o en la fanpage en Facebook. Y bien, hasta la próxima entrada.

Desarrollo dirigido por pruebas – Python y Pytest

pytest logo

Desarrollo dirigido por pruebas

Hola a todos, en esta entrada quiero hablar de un tema que me gusta mucho, y que estoy seguro a ustedes también, hablo del desarrollo dirigido por pruebas o TDD. En esta entrada veremos que es TDD, algunos ejemplos y conoceremos una excelente herramienta para llevar esta metodología de desarrollo a la práctica, Pytest.

¿Qué es el desarrollo dirigido por pruebas o TDD?

TDD proviene de Test-Driven Development, lo cual no es más que una técnica de diseño e implementación de software incluida dentro de la metodología ágil. TDD es una técnica para diseñar software que se centra en tres pilares fundamentales:

  • La implementación de las funciones justas que el cliente necesita y no más.
  • La minimización del número de defectos que llegan al software en fase de producción.
  • La producción de software modular, altamente reutilizable y preparado para el cambio.

Al dar los primeros pasos en este tema, muchos suelen caer en la idea equivocada de que TDD se utiliza para que el proyecto, o mejor aún, el código que se está escribiendo, termine cargado con una amplia cobertura de pruebas (casos de uso), y aunque esto no es del todo herrado, y siempre se agradece, la idea principal detrás de TDD es convertir a los programadores en verdaderos desarrolladores.

¿Qué quiero decir con esto? En principio, cualquier persona después de un tiempo de leer libros y ver videos en internet, puede escribir código, pero para considerarse un verdadero profesional, debes ir más allá, conocer metodologías, patrones de diseño de software, pruebas unitarias, etc. Y para lograr esto, TDD nos ayuda bastante.

Cuando por fin nos sentimos cómodos trabajando con TDD (desarrollo dirigido por pruebas) podemos contar con características que de otra manera, sería muy laborioso añadir a nuestro flujo de trabajo en el diseño de software.

Ciclo de un desarrollo dirigido por pruebas

  • Enfocarse en un requerimiento a la vez: Se elige de una lista de requerimientos, aquél que se cree que nos dará mayor conocimiento del problema y que a la vez sea fácilmente implementable.
  • Escribir una prueba: Se comienza escribiendo una prueba para el requisito. Para ello el programador debe entender claramente las especificaciones y los requisitos de la funcionalidad que está por implementar. Este paso nos orilla como programadores a tomar la perspectiva de un cliente considerando el código a través de sus interfaces.
  • Verificar que la prueba falla: Si la prueba no falla es porque el requerimiento ya estaba implementado o porque la prueba no ha sido escrita correctamente.
  • Escribir la implementación: Escribir el código lo más sencillo posible, a modo de que haga que la prueba funcione. Se usa la expresión “Mantenlo simple, Es**.” (“Keep It Simple, Stupid!”), conocida como principio_KISS.
  • Ejecutar las pruebas automatizadas: Verificar que todas las pruebas escritas funcionan correctamente.
  • Eliminación de duplicación de código: El paso final es la refactorización, que se utilizará principalmente para eliminar código duplicado. Se van añadiendo pequeños cambios al código a modo de iteraciones, siempre asegurandose de ejecutar las pruebas para asegurarse de que mantiene un correcto funcionamiento.
  • Actualización de la lista de requisitos: Se actualiza la lista de requerimientos tachando el requerimiento implementado. Asimismo se agregan requerimientos que se hayan visto como necesarios durante este ciclo y se agregan requerimientos de diseño, ya que puede darse el caso en que se encuentre un requerimiento que se encuentre ligado a uno ya establecido previamente.

Una de las mayores ventajas de escribir código utilizando TDD es que rara vez tienes que hacer uso de un depurador. Aunque como cualquier cosa tiene sus desventajas, la más importante, es que para llevar a cabo esta práctica correctamente se requiere de mucha paciencia y dedicación para que las pruebas (casos de uso) que establezcamos sean lo más adecuados posibles.

Ejemplos de TDD (desarrollo dirigido por pruebas) con Python

pytest logoPara los siguientes ejemplos voy a hacer uso de mi librería de testing preferidad de las opciones que podemos encontrar para Python, hablo de Pytest.

¿Qué es Pytest?

Cómo lo describen en su página oficial:

“The pytest framework makes it easy to write small tests, yet scales to support complex functional testing for applications and libraries.”

Y es que es verdad, existen bastantes opciones para desarrollar mediante TDD con Python, pero sólo con Pytest he podido encontrar esa flexibilidad y facilidad con la que me siento tan contento. Para utilizar pytest, basta con instalarlo como cualquier otro paquete


$ pip install pytest

Para escribir nuestras pruebas, debemos hacerlo utilizando archivos con el prefijo “test_”.

Realicemos un sencillo ejemplo del ciclo de desarrollo con TDD. Primero creamos un directorio de trabajo y nos posicionamos dentro del mismo.


$ mkdir [DIRECTORIO] && cd [DIRECTORIO]

No te olvides de reemplazar [DIRECTORIO] con el nombre que le quieras dar tu mismo, en mi caso será tdd_example. Ahora, en este directorio creamos el archivo donde escribiremos nuestro código, en mi caso se llamará test_add.py.


$ touch test_add.py

Ahora, comencemos a escribir nuestro código siguiendo TDD.

  • Recordando el ciclo del desarrollo dirigido por pruebas, debemos elegir un requerimiento, en mi caso será sumar 2 números.
  • Escribimos nuestra prueba.

# Prueba la función con los valores (4, 5)
# Resultado: 9 (True)
def test_add():
assert add(4, 5) == 9

  • Verificamos que la prueba implementada falle, ya que en este punto el requerimiento no se encuentra implementado.

$ pytest

Veremos como nos aparecen mensajes de error, diciendo que no se encuentra implementado el método add, justo lo que esperabamos.

  • El siguiente punto es escribir nuestra implementación.

def add(x, y):
return x + y

  • Ahora, volvemos a ejecutar la prueba para validar el correcto funcionamiento de nuestra implementación.

$ pytest

Nos dará una salida con información de la ejecución, y un mensaje diciendo que todo ha sido ejecutado correctamente.

Y bien, creo que es todo por ahora, aún faltaron algunos pasos, pero siendo un ejemplo tan básico, no lo vi necesario, así mismo, invito a todos a que realicen experimentos más complejos, y lean la documentación de pytest para que lo implementen en sus desarrollos del día a día.

Espero te haya agradado esta entrada, y cualquier comentario no dudes en hacermelo saber por este medio, o en mi cuenta de Twitter.

También te invito a que me sigas en mis redes (Twitter, Facebook) y si te gusta lo que escribo, compartas el blog.

Hasta la próxima.

Primeros pasos con Axios

Consumiendo Servicios Web / REST APIs en Vuejs con Axios

Hola a todos, esta entrada es para actualizar lo visto en Realizando peticiones a un API con Vue. En esta ocasión tendremos nuestros primeros pasos con Axios, ya que como el mismo Evan You (creador de Vuejs) nos adelantaba, será retirado de los proyectos oficiales y se invita a utilizar librerías como Bluebird o Axios.

¿Qué es Axios?

Axios es un cliente HTTP basado en Promesas para Javascript, el cual puede ser utilizado tanto en tu aplicación Front-end, como en el Back-end con Nodejs. Utilizando Axios, es muy sencillo enviar peticiones a endpoints REST y realizar operaciones CRUD. Además, Axios puede ser utilizada desde una aplicación desarrollada con Javascript plano, al igual que utilizando un Framework como Vuejs. Para visualizar una lista completa con las caracteristicas de Axios, pueden visitar su página en Github, aunque aquí les menciono las que en mi opinión son las más importantes.

  • Realizar peticiones XMLHttpRequest (Ajax) desde el navegador de una manera sencilla.
  • Realizar peticiones HTTP desde Nodejs.
  • Soporta el API de Promesas.
  • Intercepta peticiones y respuestas.
  • Transforma la información de las peticiones y respuestas.
  • Cancela peticiones.
  • Transforma automáticamente la información en formato JSON.
  • Soporta protección del lado del cliente contra ataques CSRF (Cross-site request forgery).

En las próximas líneas, mi objetivo será que aprendas a instalar y añadir Axios a tu proyecto.

¿Qué vamos a realizar?

Para mostrar de forma más clara el tutorial, realizaremos una sencilla pero útil para el aprendizaje lista de posts. Pueden ver el acabado final en la siguiente imágen:

primeros pasos con axios - ejemplo

Primeros pasos con Axios…

Para añadir Axios, existen dos maneras:

Opción 1: Instalando Axios con Node Package Manager.

Para esto, sólo necesitas ejecutar uno de los siguientes comandos:


# Con npm

$ npm install -S axios

# Con yarn

$ yarn add axios

 

 

Con esto instalamos la librería dentro del directorio node_modules de nuestro proyecto.

Opción 2: Utilizando un CDN

La manera más sencilla de incluir axios es utilizando un Content Delivery Network, por ejemplo, incluyendo la siguiente etiqueta script en tu archivo index.html:


<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

 

 

Como lo que buscamos es probar la funcionalidad de Axios para el envío y recepción de información desde servicios web/ REST, necesitamos tener un backend, como esto está fuera del alcance de este tutorial, vamos a utilizar la instancia para pruebas del servidor JSON que se encuentra en http://jsonplaceholder.typicode.com/ la cual ofrece varios endpoints para pruebas.

Especificamente, haremos uso del endpoint http://jsonplaceholder.typicode.com/posts.

Implementación de la UI

Para esta entrada utilizaremos el siguiente código HTML:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Getting started with Axios</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.7/lumen/bootstrap.min.css">
</head>
<body>
<div class="container">
<div class="jumbotron">
<h1>Getting started with Axios and Vanilla javascript</h1>
<h4>This application uses Axios.</h4>
</div>
<h2>Axios Demo by <small>LaEsporaDelHongo.com</small></h2>
<div class="panel panel-primary">
<div class="panel-heading">GET Request</div>
<div class="panel-body">
<button class="btn btn-primary" onclick="getRequest()">Get Posts</button>
<button class="btn btn-warning" onclick="cleanResult(this)">Clear</button>
<div class="panel-body" id="getResult"></div>
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">GET Request with Parameters</div>
<div class="panel-body">
<input type="text" class="form-control" id="postId" placeholder="Post ID..." /><br>
<button class="btn btn-primary" onclick="getRequestWithParams()">Get Post</button>
<button class="btn btn-warning" onclick="cleanResult(this)">Clear</button>
<div class="panel-body" id="getResultWithParams"></div>
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">POST Request</div>
<div class="panel-body">
<form class="form-inline" id="postInputForm">
<div class="form-group">
<input type="text" class="form-control" id="postTitle" placeholder="Post Title..." />
</div>
<button type="submit" class="btn btn-primary">Send</button>
</form><br>
<button class="btn btn-warning" onclick="cleanResult(this)">Clear</button>
<div class="panel-body" id="postResult"></div>
</div>
</div>
<div class="fotter">
<p>&copy; <a href="http://laesporadelhongo.com" target="_blank">LaEsporaDelHongo.com</a></p>
</div>
</div>
<!-- Axios Library -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="main.js"></script>
</body>
</html>

 

Se puede apreciar que utilizamos un tema de bootstrap, y añadimos las secciones de nuestra aplicación. También hacemos referencia al script de Axios y añadimos un archivo main.js donde se encuentran los métodos que vamos a utilizar.

Cada sección de la aplicación se encuentra definida entre los bloques de código:


<div class="panel panel-primary">...</div>

 

Cada sección contiene el código necesario para uno de los casos de uso de Axios que veremos a continuación, y que nos permitirá generar código utilizando la respuesta devuelta por el API. El código HTML de cada sección respectivamente:


<div class="panel-body" id="getResult"></div>

<div class="panel-body" id="getResultWithParams"></div>

<div class="panel-body" id="postResult"></div>

 

Donde la unica diferencia se encuentra en el atributo id de cada bloque.

El código JS que contiene el archivo main.js es el siguiente:


function generateSuccessHTMLOutput(response) {
return  '<h4>Result</h4>' +
'<h5>Status:</h5> ' +
'<pre>' + response.status + ' ' + response.statusText + '</pre>' +
'<h5>Headers:</h5>' +
'<pre>' + JSON.stringify(response.headers, null, '\t') + '</pre>' +
'<h5>Data:</h5>' +
'<pre>' + JSON.stringify(response.data, null, '\t') + '</pre>';
}

function generateErrorHTMLOutput(error) {
return  '<h4>Result</h4>' +
'<h5>Message:</h5> ' +
'<pre>' + error.message + '</pre>' +
'<h5>Status:</h5> ' +
'<pre>' + error.response.status + ' ' + error.response.statusText + '</pre>' +
'<h5>Headers:</h5>' +
'<pre>' + JSON.stringify(error.response.headers, null, '\t') + '</pre>' +
'<h5>Data:</h5>' +
'<pre>' + JSON.stringify(error.response.data, null, '\t') + '</pre>';
}

function cleanResult(e) {
// e.nextElementSibling it's the result container
e.nextElementSibling.innerHTML = '';
}

function getRequest() {
var resultEl = document.getElementById("getResult");
resultEl.innerHTML = "";
// We use Axios to perform a GET request
axios.get('http://jsonplaceholder.typicode.com/posts')
.then(function(response) {
console.log(response);
resultEl.innerHTML = generateSuccessHTMLOutput(response);
})
.catch(function(error) {
resultEl.innerHTML = generateErrorHTMLOutput(error);
})
}

function getRequestWithParams() {
var resulEl = document.getElementById('getResultWithParams');
var postId = document.getElementById('postId').value;
resulEl.innerHTML = '';
// We use Axios to perform a GET request with params
axios.get('http://jsonplaceholder.typicode.com/posts', {
params: {
id: postId
}
})
.then(function(response) {
console.log(response);
resulEl.innerHTML = generateSuccessHTMLOutput(response);
})
.catch(function(error) {
resulEl.innerHTML = generateErrorHTMLOutput(error);
});
document.getElementById('postId').value = '';
}

function getPostRequest(e) {
e.preventDefault();
var resultEl = document.getElementById('postResult');
var postTitle = document.getElementById('postTitle').value;
resultEl.innerHTML = "";
// We use Axios to perform a POST request.
axios.post('http://jsonplaceholder.typicode.com/posts', {
userId: '1',
title: postTitle,
completed: true
})
.then(function(response) {
console.log(response);
resultEl.innerHTML = generateSuccessHTMLOutput(response);
})
.catch(function(error) {
resultEl.innerHTML = generateErrorHTMLOutput(error);
});
document.getElementById('postTitle').value = '';
}
document.getElementById('postInputForm').addEventListener('submit', getPostRequest);

 

De este archivo, podemos observar que contamos con un par de funciones para generar código HTML, el cual será insertado en cada bloque mencionado anteriormente. También tenemos una función con la cual se limpian los elementos input, y las funciones con las cuales llevaremos acabo las peticiones al API.

Estas funciones cuentan con un sencillo código javascript, donde sólo cabe mencionar la sección de Axios:


# Get request

axios.get(url)

# Get request with params

axios.get(url, params)

# Post request

axios.post(url, params)

 

Axios en cada petición nos devuelve una promesa, la cual debemos manipular haciendo uso de los métodos .then/.catch para capturar la respuesta y los errores respectivamente.

Nota final con respecto a Vuejs

Para utilizar Axios con vuejs contamos con dos maneras de llevar acabo esto:


# Utilizando Axios de forma normal

import axios from 'axios'

axios.get(url)

# Utilizando Axios como si de Vue-resource se tratara.

import axios from 'axios'

Vue.prototype.$http = axios

this.$http.get(url)

Y bien, es todo por esta ocasión, pueden encontrar un ejemplo utilizando Vuejs y otro ejemplo con Vanilla js (el utilizado en esta entrada) en el siguiente repositorio. Cualquier duda o comentario no duden en escribirlo en la sección de abajo, o en Twitter. Si gustas apoyarme a seguir escribiendo como hasta ahora, comparte el blog con tus amigos, conocidos, colegas, en tus redes, donde gustes. O bien siguiendome en Twitter y dando like a la fan-page de Facebook. Hasta la próxima.

Presentando Cordovue – Cordova + Vuejs + Webpack

Presentando Cordovue

Hola a todos, en esta entrada vengo a presentar el proyecto que mostré hace un tiempo en mi cuenta de Twitter,  llamado Cordovue con el cual busqué unificar dos herramientas con las que he estado trabajando mucho últimamente, Vue y Cordova/Phonegap.

El objetivo del proyecto como mencionaba antes, se trata de una “plantilla” con apenas modificacione, para utilizar todo el flujo de trabajo de Vuejs en un proyecto de Cordova/Phonegap.

  • Utiliza Webpack para minificación de archivos
  • Transpilación para escribir el código utilizando sintaxis Ecmascript6
  • Compatible con ambos frameworks, Cordova y Phonegap.
  • Permite utilizar por completo el ecosistema de Vuejs,

Estructura de un proyecto utilizando Cordovue

  • Hooks/: Ya que Cordonvue se basa en un proyecto generado con la herramienta de línea de comandos, este directorio es donde colocamos todas aquellos “scripts” con los cuales customizamos los comandos de Cordova.
  • Platforms/: Este directorio es en donde se almacenan los archivos referentes a las plataformas objetivo de nuestra aplicación (Browser, Android, iOS)
  • Plugins/: Este directorio almacena los paquetes de código que se inyectan en el webview que utiliza Cordova, para comunicarse con la plataforma nativa sobre la cual se está ejecutando la aplicación.
  • www/: Este es el directorio donde se almacena el código de la aplicación (arhivo index.html, imagenes, archivos js que intervienen en la aplicación, y hojas de estilo.)
  • .babelrc: Este archivo establece opciones para Babel, la herramienta que “transpila” el código escrito utilizando la nueva sintaxis de Javascript.
  • config.xml: Este archivo define las configuraciones que se utilizan para construir nuestra aplicación.
  • webpack.config.js: Para empaquetar, transpilar, minificar, y llevar acabo otras tareas de desarrollo, ,se utiliza Webpack, y este archivo define las configuraciones para  conseguir el mejor flujo de trabajo.

 

Creando una aplicación de ejemplo

Ahora que conocemos cómo está definido el proyecto, veamos un ejemplo de su utilización:

Podemos realizar esto de 3 formas diferentes que veremos a continuación:

Vía Git

$ git clone https://github.com/TheMushrr00m/cordovue.git MyAwesomeApp
$ cd MyAwesomeApp
$ yarn install
$ yarn run build
$ yarn run android
$ yarn run ios

Vía Phonegap

$ yarn global add phonegap
$ phonegap create MyAwesomeApp --template cordovue
$ cd MyAwesomeApp
$ yarn install
$ yarn run build
$ yarn run android
$ yarn run ios

Vía Cordova

$ yarn global add cordova
$ cordova create MyAwesomeApp --template=cordovue
$ cd MyAwesomeApp
$ yarn install
$ yarn run build
$ yarn run android
$ yarn run ios

Te invito a que pruebes el proyecto, y si encuentras algún error o tienes ideas de mejora la escribas en los comentarios.
Además podrías realizar un PR el repositorio del proyecto.

Eso es todo, en la siguiente entrada continuaremos el curso de Vuejs.
Saludos.

 

Curso VueJS – Realizando Peticiones a un API con Vue (Clase IV)

Realizando peticiones a un API con Vue

Hola a todos, en la entrada anterior vimos como utilizar las directivas y eventos que Vue nos proporciona, y añadimos información a nuestra aplicación en el método data de nuestro componente. En esta ocasión veremos como podemos realizar peticiones a un API con Vue y de esta manera, traer esta información desde un servidor externo y visualizarla en nuestra aplicación, podríamos realizarlo utilizando Axios, fetch, o Bluebird, pero para efectos de este curso lo haremos utilizando un plugin de Vue llamado Vue-resource.

Instalando Vue-resource

Para llevar a cabo esto, basta con ejecutar el siguiente comando


# Yarn

yarn add vue-resource

# npm

npm i vue-resource -S

Ahora debemos configurarlo, esto lo haremos en nuestro archivo main.js.

  • Primero tenemos que importar el plugin:

import Vue from 'vue'

import VueResource from 'vue-resource'

import App from './App.vue'

...

  • Una vez importado, debemos “registrarlo” dentro de Vue para poder utilizarlo en nuestra aplicación.
... 
Vue.use(VueResource)

new Vue({
...

Realizando Peticiones

Habiendo realizado lo anterior, ya podemos realizar peticiones a cualquier API. Para el caso de este curso lo haremos a la PokeAPI. Para esto vamos a modificar el bloque <script> de nuestro componente App.vue para quedar de la siguiente manera:

export default {
    name: 'app',
    data() {
      return {
        pokemons: []
      }
    },
    methods: {
      toggleCaptched(pokemon) {
        pokemon.captched = !pokemon.captched
      }
    },
    mounted() {
      this.$http.get('http://pokeapi.co/api/v2/pokemon/')
        .then(response => {
          if(response.status === 200) {
            this.pokemons = response.data.results.map(pokemon => {
              return {
                name: pokemon.name,
                captched: false
              }
            })
          }
        })
        .catch(error => {
          console.console(error)
        })
    }
  }

Aquí que lo único que hicimos fue modificar el método data para que nuestro vector de pokemons esté vacío. Y añadimos el método mounted, este método que pertenece a los métodos que hacen referencia al cilo de via de una aplicación Vue, se activa cuando el render ha terminado, es decir, cuando la aplicación ha sido “montada”.

Dentro de este método, utilizamos el objeto $http que nos provee el plugin que instalamos anteriormente (vue-resource), recuerda que con “this” estamos haciendo referencia a la instancia Vue de nuestro componente, por lo tanto podemos utilizar el plugin sin problemas, y de este objeto estamos utilizando el método get, al cual le estamos pasando la URL desde donde queremos recibir los datos como parámetro.

Este método utiliza promesas para realizar la petición, por ende utilizamos .then/.catch para manejar el estado de la respuesta que nos provea el servidor. Dentro del método .then recibimos un argumento, en este caso lo he llamado response y antes que cualquier cosa, verificamos que el código de respuesta del servidor sea 200 (Correcto).

De ser verdadero, modificamos nuestro vector de pokemons, pasandole todos los pokemons que vienen en la respuesta del servidor (PokeAPI segmenta la respuesta a 20, ya veremos como trabajar esto más adelante). Utilizamos el método “map” para recorrer el vector de pokemons que nos devuelve el servidor, para aplicar una función a cada elemento y poder devolver justo lo que queremos, en nuestro caso, por ahora sólo necesitamos el nombre del pokémon y un atributo “captched” cuyo valor inicial es false.

Como vemos dentro de “map” estamos utilizando return para devolver un objeto con los parámetros que necesitamos (name y captched). Si no te queda claro, la función map sirve para iterar através de los elementos de un vector, y aplicar una función, cuyo resultado de la función map, es un nuevo vector conteniendo los datos que necesitamos, por ejemplo, podríamos devolver el nombre de los pokemons de forma invertida.

Y ahora, si ejecutamos la aplicación podremos verificar que todo está correcto. Podemos visualizar una lista de pokemons como lo hacíamos anteriormente, pero ahora utilizando datos traídos desde un API.

Resultado - Realizando Peticiones a un API con Vue

Esto ha sido todo por hoy. En la próxima entrada vamos a trabajar con más componentes para nuestra aplicación y mejorar un poco nuestro código. Espero sus opiniones acerca del curso hasta ahora, y si les ha sido util para aprender les agradezco lo compartan.

Saludos.

Curso VueJS – Directivas y Eventos (Clase III)

Directivas y Eventos con VueJS

Hola, si has seguido el curso hasta ahora deberías tener una estructura de archivos en tu proyecto similar a la siguiente, de no ser el caso, por favor realiza el procedimiento descrito en la entrada anterior  y despues continuas aquí. Ahora hablaremos sobre como trabajar con Directivas y Eventos con VueJS.

Directory-structure

Directory-structure

En esta entrada aprenderemos:

  • Como poder visualizar una lista de elementos.
  • Aplicar clases dinámicamente a los elementos de nustra aplicación.
  • Manejar eventos desde los elementos de nuestra aplicación.

Pero antes, vamos a aplicar un poco de estilo a nuestra aplicación, como los estilos están fuera del alcance de esta serie de entradas, vamos a añadir una de las plantillas bootstrap gratuitas que podemos encontrar en Bootswatch.

Para lograr esto, basta con incluir los archivos que nos proporcionan, en mi caso escogí el tema Lumen, así que añado al archivo index.html una referencia a la hoja de estilos:


...

<link rel="stylesheet"

href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.7/lumen/bootstrap.min.css">
</head>
<body>

...

Ya que hicimos esto, vamos a eliminar el contenido que nos da por defecto Vue-loader.
Para esto, vamos a modificar el archivo src/App.vue. Este archivo es el componente principal de nuestra aplicación, tranquilo,
esto de los componentes lo veremos más adelante en el curso. Eliminamos todo el código, tal que el archivo debe quedar así:

<script>
    export default {}
</script>

<template>
    <div id="app"></div>
</template>

<style></style>

¿Te parece extraño? VueJS, utiliza los archivos con extensión .vue para especificar que su contenido se trata de un componente.
Como podemos observar, se trata de 3 bloques de código:

 

  • Script: Aquí se “exporta” nuestro componente, por eso obligatoriamente debemos insertar:
     export default {} 

    dentro de las llaves insertamos todo nuestro contenido js relacionado a nuestra aplicación.

  • Template: Aquí se inserta todo el código html de nuestro componente. Cada componente puede ser de un sólo bloque, esto quiere decir que necesariamente debe exportarse un solo elemento html, por ejemplo:
     <span>VueJS</span>

    o

     <div id="app"><span>VueJS</span></div> 

    , como observamos, en el segundo ejemplo, el elemento span está encerrado dentro de un bloque div, por lo tanto, estamos exportando un único elemento.

  • Style: Aquí podemos agregar el código referente a estilos de nuestro componente, gracias a Vue-loader podemos utilizar out-of-box CSS, SCSS o SASS, así como Stylus u otro pre-procesador siempre y cuando se añada a la configuración de webpack. Y si no queremos hacerlo de esta manera, siempre podemos utilizar un archivo de estilos independiente sin ningún tipo de inconvenientes.

Sabiendo esto, modificaremos el bloque script con el siguiente código:

export default {
    name: 'app',
    data() {
      return {
        pokemons: [
          {name: "Bulbasaur", captched: false},
          {name: "Ivysaur", captched: false},
          {name: "Venusaur", captched: false},
          {name: "Charmander", captched: false},
          {name: "Charmeleon", captched: false},
          {name: "Charizard", captched: false},
          {name: "Squirtle", captched: false},
          {name: "Wartortle", captched: false},
          {name: "Blastoise", captched: false},
          {name: "Pikachu", captched: false},
        ]
      }
    },
  }

 

 

Podemos observar que hemos añadido un par de atributos, primero name, este atributo es una buena práctica especificarlo en nuestros componentes, ya que nos brinda mejores opciones de depuración al brindarnos mensajes de error mas claros, así como la posibilidad de llamarse a si mismo desde el template.

Además añadimos el atributo data, el cual es una función que nos retorna un objeto con los valores que queremos pasar a nuestro template, en este caso, únicamente tenemos un vector de pokemons :D. Si, cuando utilizamos componentes en VueJS, podemos utilizar cualquier atributo de manera normal, excepto data, el cual tiene que ser llamado como una función que devuelve un objeto.

Seguidamente agregamos un poco de código html en el bloque template.


<div id="app">
    <div class="col-xs-12">
        <h1 class="text-center">Pokédex</h1>
    </div>
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <ul class="list-group">
                <li class="list-group-item text-center" v-for="pokemon in pokemons">
                    <span>{{ pokemon.name }}</span>
                </li>
            </ul>
        </div>
    </div>
</div>

 

 

Nada extraño, sólo añadimos la estructura básica de una lista de elementos, con un par de clases de estilos que nos proporciona el template que añadimos al inicio, podemos observar la primer directiva que veremos en esta entrada v-for. Esta directiva de VueJS se aplica como un atributo al elemento html sobre el cual queremos iterar. Mientras iteramos, visualizamos el nombre de cada pokemon en nuestro vector dentro del párrafo utilizando {{}}.

Hasta este punto la aplicación debería de verse de la siguiente forma:

Mostrando lista

Mostrando lista

Pero, ¿qué tal si quisieramos saber en que iteración nos encontramos? Sencillo, VueJS nos proporciona del valor $index, el cual podemos utilizar de la siguiente manera:


...

<li class="list-group-item text-center" v-for="(pokemon, $index) in pokemons">
    <span>ID: {{ $index }} - Name: {{ pokemon.name }}</span>
</li>

...

 

 

En este caso, $index toma el valor de la posición del elemento en el que nos encontramos en la iteración actual, y en el ejemplo lo utilizo como el ID del pokemon. (Claro que no existe ningún pokémon con id 0 según recuerdo :D)

Clases dinámicas

En nuestra aplicación, sería bueno saber que pokémon ya capturamos. Por ejemplo, podríamos darle un estilo diferente a estos elementos. Para esto podemos vincular el atributo class a una propiedad, utilizando la directiva v-bind o su versión corta “:”.

Con v-bind o “:” podemos tomar cualquier atributo de los elementos html y añadirle propiedades dinámicas de VueJS. Veamos esto en código. Primero modificamos el bloque script:


...

methods: {
      toggleCaptched(pokemon) {
        pokemon.captched = !pokemon.captched
      }
    }

 

 

Añadimos el atributod methods, en el cual podemos declarar todos los métodos que usaremos en nuestro componente, en este caso, sólo estamos definiendo una función que recibe como parámetro un pokémon, y modica el valor de su atributo captched. Ahora modificamos los estilos.


.captched {text-decoration: line-through;}

 

ünicamente creamos una clase que hará que el texto aparezca “tachado”.

Luego modificamos el código del template.


...

<li v-for="(pokemon, $index) in pokemons" 
            class="list-group-item">
            <div class="row">
              <div class="col-xs-8" :class="{'captched': pokemon.captched}">
                <span>ID: {{ $index }} - Name: {{ pokemon.name }}</span>
              </div>
              <div class="col-xs-4">
                <button class="btn btn-xs btn-primary pull-right" 
                  @click="toggleCaptched(pokemon)">
                  {{ !pokemon.captched ? 'Capturar' : 'Liberar' }}
                </button>
              </div>
            </div>
          </li>
...

 

Aquí estamos viendo el concepto de binding de VueJS en acción, primero modificamos un poco la estructura. Al elemento li le añadimos el atributo :class, recordemos que “:” es la versión corta de v-bind, ahí especificamos que se aplique la clase captched a todos aquellos elemenos que su atributo captched sea verdadero.

Después observamos el botón que acabamos de crear, el cual contiene la tercera directiva que veremos en esta entrada, @click. Y si lo preguntas @click es la versión corta de v-on, con esta, hacemos binding pero de eventos a los elementos de nuestra aplicación, cabe recalcar que cuando hacemos binding con v-on, o v-bind, o sus versiones cortas “:” o “@” únicamente podemos utilizar expresiones. En nuestro botón estamos definiendo que al hacer click (@click) queremos que se ejecute el método que creamos previamente y pasamos el pokémon al cual queremos afectar.

Además podemos ver que el texto del botón es una expresión que verifica el estado del atributo del pokémon y añade el texto correcto para mostrar el estado del pokémon. Además de click podemos utilizar otros eventos como keyup, mouseover, etc.

Hasta este punto nuestra aplicación debería lucir de la siguiente forma.

Final 3er entrada

Y bien, es todo por ahora, espero el curso sea de su agrado. Me gustaría me dejaras tus comentarios y nada, te espero en la siguiente.

Saludos.

Curso VueJS – Creando el proyecto (Clase II)

Configuración del proyecto VueJS

Hola a todos, en esta entrada continuo con esta serie de articulos acerca de VueJS, en la cual vamos a configurar nuestro entorno de trabajo para comenzar a construir una aplicación que integra mucho de lo que se necesira para desarrollar aplicaciones reales, como lo son los componentes, consumir servicios web, puesta a producción, etc.

La aplicación que vamos a construir será un pokédex, para tal objetivo haremos uso de la pokéapiAquí pueden observar el resultado que podrá tener la aplicación.

Vista de la aplicación ya finalizada.Vista de loader.Vista de pokemonsVista individual de pokemonAhora, supongo que ya debes tener instalado Node en tu sistema, de no ser así (instalalo ahora y vuelve aquí al finalizar) y el excelente gestor de paquetes para node Yarn (no es obligatorio, puedes utilizar “npm” sin problemas, pero es mejor actualizarse :D)

Con esto ya podemos comenzar, así que “manos al teclado”.

Primero necesitamos instalar una maravilla de herramienta, como lo es Vue-loader. Si no la conocen Vue-loader es una herramienta que nos permite utilizar Webpack en nuestro flujo de trabajo, con lo cual podremos gozar de ventajas a la hora de desarrollar nuestras aplicaciones, como la recarga automatica en cada cambio para poder visualizarlos en el navegador, brindarnos un sistema de modulos para mejorar nuestro desarrollo con JS, compilar en un sólo archivo nuestras dependencias para enviar nuestra aplicación a producción, etc.

Además Vue-loader nos brinda la posibilidad de escribir nuestros componentes en archivos separados con extensión *.vue con el siguiente formato:

¿Genial no lo creen?

 

Manos al Teclado…

Entonces, lo primero que tenemos que hacer es abrir nuestra terminal, consola o simbolo del sistema y ejecutar el comando que corresponda con el gestor de paquetes que estén utilizando:


// Si estás utilizando npm

npm i -g vue-cli

// Si estás utilizando yarn

yarn global add vue-cli

 

 

Esperamos a que finalice la instalación, y en la misma consola nos posicionamos con ayuda del comando cd en el directorio que hayamos destinado para este proyecto.

Ya que estamos en este punto, ejecutamos el siguiente comando:


vue init webpack-simple pokedex

 

 

Vue es el comando que acabamos de instalar, init es la orden que queremos que ejecute, la cual creará un nuevo directorio, con el esqueleto de una aplicación sencilla de VueJS. La siguiente parte del comando anterior es “webpack-simple”, el cual es uno de los templates que vue-loader nos ofrece para iniciar nuestros proyectos, y por último, pokedex es el nombre de nuestro proyecto.

En la consola deberíamos tener una salida como la siguiente:

Vista del resultado en la consola.Siguiente las instrucciones que nos muestra la consola podemos ejecutar la aplicación que acabamos de crear. Entonces los llevamos a cabo:


// Nos posicionamos en el directorio del proyecto.

cd pokedex

// Instalamos las dependencias del proyecto, yo usaré yarn pero pueden utilizar npm sin problema.

yarn install

// Con npm

npm install

// Cuando el proceso finalice ejecutamos lo siguiente

// Con yarn

yarn run dev

// Con npm

npm run dev

Con eso debería mostrarse en nuestro navegador por defecto la aplicación que acabamos de crear.

Vista de la aplicación completa de VueJS.Bien, es todo por esta entrada, espero haber dejado claro lo básico y que les agrade la idea de la aplicación que vamos a crear, si quieren verla en funcionamiento, pueden hacerlo en el siguiente link o también pueden revisar el repositorio en Github.

Si quieren profundizar en cualquiera de las herramientas que vimos aquí, no duden en leer su respectiva documentación, o si lo prefieren dejen sus comentarios y con gusto les responderé.

Nos vemos en la siguiente entrada.

Saludos.

 

Curso VueJS – Hola Mundo (Clase 1)

Hola a todos, en esta entrada quiero escribirles sobre está librería (progressive framework, como ellos lo denominan) que he estado probando y utilizando últimamente, y que la verdad me ha parecido increíble, se trata de VueJS [Sitio Oficial].

VueJS Logo

Si no conocías a VueJS, aquí te dejo la descripción de su sitio oficial.

Vue (pronounced /vjuː/, like view) is a progressive framework for building user interfaces. Unlike other monolithic frameworks, Vue is designed from the ground up to be incrementally adoptable. The core library is focused on the view layer only, and is very easy to pick up and integrate with other libraries or existing projects. On the other hand, Vue is also perfectly capable of powering sophisticated Single-Page Applications when used in combination with modern tooling and supporting libraries.

Básicamente VueJS, nos brinda otra opción más para tener en cuenta en nuestro patrón MVC, pudiendo ocupar el lugar de la V (View).

Pero, ¿por qué utilizar VueJS?

 

VueJS está diseñado desde cero para ser incrementalmente adaptable, cuenta con una característica llamada Declarative Rendering, que no es más que un sistema de plantillas para representar de forma declarativa datos en el DOM utilizando una sintaxis sencilla.

VueJS también nos proporciona Reactividad, y bueno, en su sitio oficial tienen una excelente comparativa con otras librerías y frameworks, como lo son ReactJS, EmberJS y AngularJS.

Y bien, a lo que estamos aquí, veamos un sencillo ejemplo de lo que nos aporta VueJS, realizando el mundialmente conocido “Hello World”:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <title>Hello World with VueJS!</title>
</head>
<body>
  <div class="container">
    <div class="jumbotron" id="app">
      <h1 class="text-center">Vue JS - Hello World</h1>
      <p class="text-center"></p>
    </div>
  </div>

  <script src="https://unpkg.com/vue@2.0.8/dist/vue.js" charset="utf-8"></script>
</body>
</html>

Como podemos notar, sólo tengo la estructura básica de una página HTML, en la cual hago referencia a Bootstrap y a VueJS desde el CDN que recomiendan en su sitio oficial.

Ahora justo antes de la etiqueta de cierre de body abrimos una nueva etiqueta de script para meter nuestro código de Vue y escribimos lo siguiente.

new Vue({
  el: '#app',
  data: {
    message: 'Hello, VueJS!'
  }
});

Como podemos ver, simplemente estamos creando una nueva instancia de Vue,
y declarando unos valores que recibe el objeto constructor de Vue.
Primero tenemos “el”, que recibe el elemento donde VueJS trabajará, aquí podemos
pasar cualquier tipo de selector CSS valido.
Luego tenemos “data”, el cual es un objeto, donde pasamos los datos que queremos que
se muestren en nuestra vista, aquí únicamente estamos pasando la clave “message” con
el mensaje que queremos mostrar.

Y ahora, si notaron en el código HTML tenemos una etiqueta p vacía,
la modificamos para que quede de la siguiente manera:

<p class="text-center">{{message}}</p>

Quedando nuestro código así:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <title>Hello World with VueJS!</title>
</head>
<body>
  <div class="container">
    <div class="jumbotron" id="app">
      <h1 class="text-center">Vue JS - Hello World</h1>
      <p class="text-center">{{message}}</p>
    </div>
  </div>

  <script src="https://unpkg.com/vue@2.0.8/dist/vue.js" charset="utf-8"></script>
  <script type="text/javascript">
    new Vue({
      el: '#app',
      data: {
        message: 'Hello, VueJS!'
      }
    });
  </script>
</body>
</html>

Ahora, si todo está correcto, podemos visualizar nuestro archivo en el navegador
y veremos algo como esto:
Clase 1 - VueJS
Bien, por ahora es todo, este es la introducción a esta serie de entradas que tendremos sobre este grandioso y potente framework.

Puedes encontrar el código en este repositorio de GitHub.

Si te gustó por favor, no dudes en compartirlo, y dejar tus comentarios.
Saludos.