Aprender VueJS con 100 ejercicios prácticos

Tekst
0
Recenzje
Przeczytaj fragment
Oznacz jako przeczytane
Czcionka:Mniejsze АаWiększe Aa

Métodos
OPERANDO CON LAS PROPIEDADES

Dentro de una instancia Vue además de las propiedades se exponen métodos que operan sobre los datos o ejecutan acciones. Los métodos se ejecutan cada vez que las invocamos, cosa que no ocurre con las propiedades computadas, ejecutadas cada vez que alguna de las variables utilizadas en la obtención de un resultado en las propiedades computadas cambia su valor; en dicho caso se ejecutaría la propiedad, para recalcular.

Estos métodos se declaran dentro de la instancia dentro del bloque methods, y se pueden asociar a los elementos HTML de la instancia.

En este ejercicio vamos a relacionar un componente de tipo botón con una acción que se corresponderá con un método declarado en la instancia Vue. Para indicar esta relación usamos la directiva v-on que se coloca dentro del HTML del botón y el evento (en este caso el evento de click).

<button type=”button” v-on:click=”showMessage”>Mostrar Título</button>

Una vez dado este paso creamos un bloque methods en la instancia y dentro de este creamos la función showMessage que concatenará la propiedad title a un texto.

methods: {

showMessage: function() {

console.log(‘Showing message: ‘+this.title + ‘ Aprendamos!’);

return this.title + ‘ Aprendamos!’;

}

}

Posteriormente declaramos dentro de una etiqueta h1 el método para renderizar el resultado de la función [1].

<h1>{{ showMessage() }}</h1>

Para volver a renderizar el resultado de la función accionamos el botón, si nos fijamos se calcula cada vez que salta el evento asociado al botón [2].



Componentes de la instancia
INSTANCIA VUE

Hasta ahora hemos estado jugando con la instancia de Vue, su ciclo de vida, el renderizado y el doble enlazado de propiedades, los métodos, etc., pero no nos hemos parado con los bloques básicos que tiene.

Una instancia se compone de:

• $el: es el objeto componente HTML al que estará asociado mediante el id correspondiente

• $data: es el objeto que contiene las propiedades de la instancia

• $refs: es el objeto donde se registran los elementos marcados con el atributo ref.

Para ilustrarlo en este ejercicio hemos creado una instancia de Vue con cada uno de los bloques mencionados a la que hemos añadido unas sentencias que imprimen por consola cada uno de estos elementos para que podamos ver su contenido cuando se carga la página.

El contenido de $el es efectivamente el objeto que contiene la definición del HTML de nuestra instancia. Si inspeccionamos el objeto accediendo a la propiedad innerHTML nos devuelve en formato texto el contenido en lenguaje HTML [1].

El contenido de $data nos devuelve el objecto con las variables como la de nuestro ejercicio la denominada message.

Podemos también invocar los métodos de nuestra instancia tal y como vemos en el ejercicio y nos ejecutará la función.

Dentro de $refs tenemos un objeto con los elementos marcados con el atributo ref en el HTML de nuestra instancia, en este caso son dos elementos h2 (mysubtitle y mysubtitle2).

Hemos añadido un botón que tiene asociado el método clickedButton y si lo accionamos se nos mostrarán dos mensajes en los elementos h2 referenciados. En este método accedemos a las propiedades de los componentes para añadirles un mensaje y un estilo que se hará visible en nuestra página una vez se ejecute [2].



Eventos
ESCUCHANDO EVENTOS

Podemos empezar a escuchar eventos añadiendo al input la directiva v-on seguido de que evento queremos escuchar para reaccionar invocando a un método concreto.

Hasta ahora hemos visto el doble enlazado de las propiedades de nuestra instancia, dentro del bloque data. Podemos declarar una propiedad que se renderiza en nuestra interfaz de usuario y declaramos un input que pueda modificarla mediante la directiva v-model [1].

De esta forma, cada vez que modifiquemos el contenido del input se modificará la propiedad y se renderizará inmediatamente. Sin embargo, ¿cómo haríamos si queremos que se modifique solamente cuando se finalice su edición? ¿Cuándo detectamos que se ha acabado la edición?

En este caso vamos a interpretar que se acaba de editar el valor cuando se pulsa la tecla Enter de nuestro teclado. Para ello tendremos que detectar esta pulsación y esto lo podemos conseguir con la directiva v-on diciendo que ejecutaremos una acción justo cuando se deje de presionar (modificador keyup) la tecla Enter (modificador .enter)

v-on:keyup.enter=”onEnterPressed”

De esta forma vemos que cuando dejamos de escribir y cuando soltamos la tecla Enter se ejecuta la acción que hemos definido, que no será otra que la de renderizar el contenido de la variable en la página [2].

Comprobamos además que solo se ejecuta en este caso como se puede ver en el log de la consola en la que se imprime un mensaje cuando se llama.

Escuchar eventos de teclado suele ser una práctica muy común para interceptar eventos según ocurran. Para invocar determinadas acciones, hemos probado el evento keyup. Además, podemos establecer un modificador concreto a invocar tras la captura del evento “haber pulsado una tecla”, por ejemplo, capturar una tecla en concreto, la tecla escape o incluso definir alias para las F del teclado. Esto último se realizaría mediante la configuración en Vue de los códigos de tecla: “Vue.config.keyCodes.f” [3].



Renderizar HTML
HTML EN UNA PROPIEDAD

En este ejercicio veremos cómo añadir código HTML para que sea renderizado dentro de nuestra instancia Vue.

En principio podríamos pensar que es algo muy sencillo, ¿no? Creamos una nueva instancia dentro de un elemento, una propiedad myhtml dentro del bloque data a la que asignamos una cadena con el formato de marcado HTML y la mostramos dentro de un bloque {{ myhtml }} [1].

¿Esto funcionaría? Bueno, la respuesta en este caso sería negativa ya que dentro de la instancia no se renderizaría nuestro código HTML si no como un simple texto. Esto es así para evitar una vulnerabilidad crítica en la web (XSS: cross site scripting) que pudiera permitir una modificación maliciosa del código HTML de la variable.

¿Y no existe ninguna forma de añadir código HTML? Sí que la hay, Vue nos da una directiva específica, que igualmente deberemos utilizar siempre con cuidado, denominada v-html.

En el ejercicio declaramos la variable html con el contenido a renderizar que simplemente es un título y un link a otra página y dentro de un elemento div indicamos mediante la directiva v-html que dentro se renderizará el código HTML. Fácil ¿verdad? [2]



Vincular propiedades
USO DE V-BIND

Con la directiva v-bind podemos vincular un atributo de algún elemento html a una propiedad de nuestra instancia [1].

Así contado parece algo abstracto pero para ilustrarlo en este ejercicio tendremos simplemente dos elementos: un área en la cual se van a mostrar imágenes y un botón que, cuando lo accionemos, modificará esta imagen.

Para la imagen tendremos un elemento HTML como img que se encarga de mostrar una imagen que le indiquemos dentro de la propiedad src.

<img src=”placeholder.jpg” alt=”placeholder”>

Por otro lado en nuestra instancia tenemos una propiedad llamada image que tendrá la ruta a la imagen que queremos mostrar.

Ahora simplemente tendremos que vincular o enlazar la propiedad image con el atributo src del elemento img mediante la directiva v-bind.

<img v-bind:src=”image”></img>

Una alternativa al v-bind sería utilizar los dos puntos, es decir, en lugar de “v-bind:src=…”, podríamos utilizar “:src=…”, muy útil a la hora de trabajar, por ahorrarnos tener que escribir más de la cuenta. Por lo que podríamos trabajar indistintamente con cualquiera de las dos alternativas.

Finalmente, añadimos el botón con una directiva v-on, que escuchará el evento click, que podríamos también haber simplificado con un @click, en lugar de v-on:click , para ejecutar el método responsable de cambiar el valor de la propiedad y cargar una nueva ruta de imagen al azar [2] y 3].

 

De esta forma tan sencilla hemos ejemplificado la definición que hablábamos al principio. Hemos enlazado un atributo de un elemento HTML con una propiedad de nuestra instancia.




Condicionales
USO V-IF Y V-ELSE

Durante el desarrollo de una aplicación es seguro que se nos presentarán ocasiones en las que queramos renderizar un bloque u otro de nuestra interfaz de usuario en función de alguna determinada condición.

En este caso haremos uso de las directivas v-if y v-else y, como ejemplo de las mismas, crearemos un nuevo ejercicio en el que en base a un selector mostraremos uno u otro bloque [1].

En este pequeño ejercicio se pregunta al usuario qué le gusta más: los gatos o los perros; y en función de su elección mostraremos un mensaje y una foto de su animal favorito.

La directiva v-if siempre contiene una condición en su interior, del estilo v-if=”miCondicion”, si quisiéramos añadir una segunda alternativa al bloque anterior, proseguiríamos con un “sino si…”, es decir “v-else-if”, también acompañada por una condición en su interior como la anterior. En caso de añadir la condición de, si no se han cumplido todas las anteriores, entonces habilita este bloque, utilizaríamos la directiva v-else, sin condición.

Para llevarlo a cabo necesitaremos una propiedad de la instancia Vue que denominaremos pet, que ligaremos con la directiva v-model al selector. Al seleccionar uno de los valores posibles se dispara un cambio en las diferentes propiedades de la instancia. Posteriormente crearemos los dos bloques con el contenido opcional y los marcaremos con las directivas v-if y v-else. Estas directivas evalúan la condición y, en función de lo escogido, en el selector se mostrará el bloque del perro 2 o del gato 3.




Listas
RENDERIZADO DE LISTAS

Otra situación típica en la creación de nuevas interfaces de usuario es la enumeración de elementos dentro de una lista. Para ello en Vue se utiliza la directiva v-for a la que se le pasa una colección de elementos que se representarán dentro del bloque.

Como ejercicio plantearemos una clásica lista de la compra. Simplemente crearemos dentro de la instancia Vue una propiedad que denominaremos shoppingList que es un array de cadenas de texto que representan cada uno de los productos de la lista.

Con la propiedad definida solo nos resta indicar mediante la directiva v-for que iteraremos por cada producto de nuestra lista de la compra y renderizaremos cada elemento de la lista <li>.

<ul>

<li v-for=”product in shoppingList”> {{ product }} </li>

</ul>

Con esta simple definición ya tenemos nuestra lista de la compra. [1]

Modificando ligeramente el código podemos añadir un nuevo input que añada elementos a mi compra con algunos mecanismos que hemos aprendido en anteriores ejercicios. De esta forma vemos cómo si añadimos otro nuevo elemento a nuestra lista de productos se actualiza nuestra compra [2].



Enumeración de propiedades
V-FOR PARA OBJETOS

Hemos visto cómo mostrar una enumeración de productos de nuestra lista de la compra con la directiva v-for y en este ejercicio veremos cómo mostrar un listado de las propiedades de un objeto de nuestra instancia Vue.

Tenemos una propiedad dentro de la instancia Vue que es un objeto que representa la información de uno de los posts de nuestro blog y que queremos renderizar.

post: {

title: ‘Nuevo artículo’,

date: ‘24/03/2019’,

author: ‘Ramón’,

}

Ahora lo que tenemos que hacer es usar la directiva v-for con el siguiente formato, descomponiendo el objeto en sus propiedades en pares clave-valor.

<ul>

<li v-for=”(value, key) in post” v-blue>

{{ key }}: {{ value }}

</li>

</ul>

También podríamos usar el índice en esta descomposición, si lo necesitáramos, de la siguiente manera:

<ul>

<li v-for=”(value, key, index) in post”

style= “list-style-type:none;” v-blue>

{{ index + 1 }} => {{ key }}: {{ value }}

</li>

</ul>

Podemos ver el resultado de la inspección del objeto en la imagen [1] y para seguir jugando con nuestro ejemplo meter un nuevo atributo y ver cómo se renderiza perfectamente cuando guardamos. [2]



Filtros
MODIFICADORES DE VALOR

Vamos a imaginarnos que tenemos nuestra interfaz que renderiza la lista de la compra que hemos realizado en anteriores ejercicios. Hemos sacado la aplicación que muestra la lista de la compra pero los usuarios se quejan de que se muestran en letras minúsculas y ellos quieren que se vea bien grande y se muestre en letras mayúsculas aun cuando ellos los introduzcan en minúsculas.[1]

Podremos modificar este comportamiento con una herramienta que pone a nuestra disposición Vue: los filtros.

Definiremos un filtro que pase a mayúsculas cada valor que se le pase en este caso de la siguiente forma:

Vue.filter(‘productName’, function(value){

if(!value) return ‘’

value = value.toString();

return value.toUpperCase();

});

Y en la declaración HTML lo haremos de la siguiente forma

<ul>

<li v-for=”product in shoppingList”>

{{ product | productName }}

/li>

</ul>

Esta notación es el típico pipe que es muy común y que en este caso se podría leer algo así como “a este valor la aplico esta función o transformación”.[2]



Renderizar solo una vez
DIRECTIVA V-ONCE

En caso de que necesitemos mostrar un único valor cuando carguemos la página haremos uso de una directiva especial llamada v-once. Esta directiva asegura que un elemento solo tomará un valor durante el renderizado y, en el caso de que la página se vuelva a renderizar, considerará al elemento como un elemento estático que no se tomará en cuenta de nuevo.

Una razón por la que se puede marcar un elemento con la directiva v-once sería optimizar el rendimiento en la actualización de datos. El contenido del elemento que se renderice una sola vez podría ser costoso.

En este ejemplo vemos cómo se renderiza una sola vez aquello que tengamos dentro de la variable incluida en el input [1].

Si posteriormente a la carga modificamos el contenido del input y, por tanto, el contenido de la variable podemos comprobar cómo no se renderiza de nuevo el contenido de nuestro título [2].



Mouse move
DIRECTIVA V-ON:MOUSEMOVE

En esta ocasión vamos a ver dentro de las directivas para capturar eventos del DOM aquella que nos permite filtrar los generados cuando el ratón se mueve por encima de uno de nuestros componentes.

Estamos hablando de la directiva v-on acompañado del evento mousemove [1]:

<div class=”mousearea” v-on:mousemove=”move”></div>

A este div le daremos unas dimensiones mediante la clase CSS mousearea [2]:

.mousearea {

width: 300px;

border: 15px solid green;

padding: 50px;

margin: 20px;

}

Enlazaremos el evento con una función de la instancia para ir modificando las coordenadas mientras el ratón está en movimiento. Estas coordenadas las guardaremos y las mostraremos en otro div diferente como resultado.

methods: {

move:function(event){

this.mouseX = event.clientX;

this.mouseY = event.clientY;

}

}

<div class=”result”>{{mouseX}} - {{mouseY}}</div>

A medida que se captura el movimiento del ratón se ejecuta la función y vamos refrescando las variables de la instancia que se renderizarán en nuestra página [3].




Directivas personalizadas
DEFINIENDO UNA DIRECTIVA GLOBAL

Vue permite la creación y registro de nuevas directivas a las que podremos dotar el comportamiento personalizado que queramos.

Las directivas personalizadas en Vue como el resto suelen empezar por v- y el nombre de la directiva. Como primer ejemplo empezaremos definiendo una directiva muy simple que cambie el color del texto renderizado.

De esta forma tendríamos una declaración tal que así:

<h1 v-red>Aprendiendo Vue!</h1>

En la que modificaremos el color del título a rojo tal y como indica la propia directiva. El código necesario en Javascript para definir la directiva sería el siguiente:

Vue.directive(“red”, function(el, binding, vnode) {

el.style.color = “red”;

});

Este código se ejecutará en el bind que es una función que se llama solo una vez cuando se enlaza la primera vez la directiva al elemento. Siendo más estrictos podríamos escribirlo así y con más funciones en función de cuando se quiere ejecutar el código.

Vue.directive(“red”, {

bind: function(el, binding, vnode) {

el.style.color = “red”;

}

});

Poniendo todo junto en el ejercicio como resultado tendríamos nuestros textos cambiados a color rojo ya que modificamos la propiedad color del estilo del elemento [1].

Para seguir jugando con nuestro ejemplo podríamos definir otra directiva con el color azul y aplicarla al otro texto y ver el resultado[2].



Directivas personalizadas II
DIRECTIVAS CON ARGUMENTOS

Hemos visto cómo crear una directiva personalizada muy sencilla y en este nuevo ejercicio haremos una pequeña variación para que sea algo más genérica. Veíamos que para definir nuevos colores teníamos que crear nuevas directivas pero si tenemos que crear una para cada color… vaya lío, ¿no?

 

Lo ideal es que pudiéramos indicarlo de alguna forma y solo mantener una directiva y, para conseguirlo, sería genial poder tener una única directiva y pasarle un argumento con el color. ¡Esto es lo que vamos a hacer en este ejercicio!

<h1 v-color:blue>{{message}}</h1>

<p v-color:red> Usando la directiva personalizada v-color:arg! </p>

Declaramos la nueva directiva como v-color pero además le pasamos como argumento el color deseado de forma que colorearemos diferente cada texto según el argumento dado.

Si vamos a la definición podremos hacer algo como esto:

Vue.directive(“color”, function(el, binding, vnode) {

el.style.color = binding.arg;

console.log(binding);

});

El objeto binding guarda muchas propiedades como el nombre de la directiva, el valor, los modificadores, etc., y entre estas propiedades también podemos obtener el argumento [1]. Es este argumento el que recuperaremos y con el que podremos modificar la propiedad color del estilo del elemento [2].



Directivas personalizadas III
UTILIZANDO MODIFICADORES

En este nuevo ejercicio utilizaremos más propiedades de las directivas, hasta hora hemos visto como crear una directiva que cambia el color de un texto. Una muy simple con un comportamiento estático modificando el estilo del texto y otra un poco más avanzada en la que introducimos un parámetro.

En esta ocasión introduciremos el uso de los modificadores, que son simplemente nuevos decoradores que se le pueden añadir o no a la directiva.

Volviendo a las modificaciones de estilo de los textos, un buen ejemplo sería decidir el formato en función de ciertos modificadores. Para ello crearemos la directiva v-format que podrá recibir diferentes modificadores que cambien el estilo del texto del elemento.

Los modificadores se declaran a partir de un punto y seguido al nombre de la directiva u otro modificador. Este podría ser un ejemplo de declaración:

<h1 v-format.bold.underline.highlight>{{message}}</h1>

Para el código Javascript tendríamos algo como lo siguiente:

Vue.directive(“format”, function(el, binding, vnode) {

const modifiers = binding.modifiers; if (modifiers.underline) {

el.style.textDecoration = “underline”;

}

if (modifiers.bold) {

el.style.fontWeight = “bold”;

}

if (modifiers.highlight) {

el.style.background = “#eaeaea”;

}

});

En el objeto binding tenemos los modificadores [1] que pueden haberse aplicado y que podremos consultar y aplicar en caso de que existan [2].