vue js (2): propiedades

Introducción a las propiedades y los watch de vue.js

Nicholas Krushenick

archivado en: JavaScript / 20 marzo, 2017 / taller:

En la introducción de este taller dedicado a vue.js vimos en qué consistía el data-binding y cómo se lanzaban eventos atacando directamente el DOM, como si fuera un  sistema de templates como Handlebars o similar, engarzando una instancia con algún elemento que definíamos en la propiedad el.

<div id="foo">

{{ greetings }}

</div>

<script>

var foo = new Vue({

el: '#foo',

data: {

greetings: 'Hello World!'

}

});

</script>

En esta, profundizaremos algo más en las distintas maneras en que podemos relacionar el DOM con las instancias vue.

propiedades computadas

Como vimos, en la template podemos definir una propiedad del objeto data, pero también una expresión javaScript. Por ejemplo, en el caso anterior, en lugar de que se muestre la cadena «Hello World!», podríamos hacer esto para cambiar el Mundo por Saturno y que aparezca en mayúscula:

{{ greetings.replace('World', 'Saturn').toUpperCase() }}

Sin embargo, este tipo de construcciones no son muy limpias. Al final, la lógica se reparte entre la vista y el controlador y queda un código algo confuso, que obliga a mirar en dos sitios distintos para realizar cualquier cambio, por lo que en estos casos es mejor recurrir a un tipo especial de propiedades llamadas computadas (computed).

Estas propiedades se definen en un objeto denominado computed y son funciones que devuelven el valor que debe tener en el DOM. Volviendo al ejemplo de antes:

<div id="foo">

{{ greetingsSaturn }}

</div>

<script>

var foo = new Vue({

el: '#foo',

data: {

greetings: 'Hello World!'

},

computed: {

greetingsSaturn: function() {

/* this siempre apunta a la instancia */

return this.greetings.replace('World', 'Saturn').toUpperCase();

}

}

});

</script>

Tal y como explican en la documentación oficial, en estos se podría conseguir el mismo efecto llamando directamente a un método en la template.

<div id="foo">

{{ greetingsSaturn() }}

</div>

...

methods: {

greetingsSaturn: function() {

return this.greetings.replace('World', 'Saturn').toUpperCase();

}

...

Pero esta otra solución plantea a su vez un problema y es que el valor debe calcularse todas y cada una de las veces que vuelve a renderizarse la template, ya que no se cachea por ningún lado. Por el contrario, las propiedades computadas solo se recalculan cuando cambia el valor de alguna otra propiedad implicada en el proceso. Por ejemplo, en este caso, greetingsSaturn solo se recalcula cuando cambia la propiedad greetings al ser pulsado el botón.

<div id="foo">

<p>{{ greetingsSaturn }}</p>

<button v-on:click="setGreetings()">set greeting</button>

</div>

<script>

var foo = new Vue({

el: '#foo',

data: {

greetings: 'Hello World!'

},

computed: {

greetingsSaturn: function() {

return this.greetings.replace('World', 'Saturn').toUpperCase();

}

},

methods: {

setGreetings: function() {

this.greetings = 'By World!';

}

}

});

</script>

Watch

Además de las computed properties y el bindeo de métodos, vue.js cuenta con otro sistema para manejar los valores de las propiedades mediante observadores (watchers). Equivaldrían a los ng-changes de angular 1.* o los observers de polymer y consisten en métodos que se invocan de forma automática cuando cambia el valor de la propiedad observada. Estos métodos se agrupan en un objeto llamado watch y reciben como parámetro el valor cambiado:

...

watch: {

greetings: function(newVal) {

console.log(newVal); // By World!

}

}

...

Respecto a las propiedades computadas, los watchs son útiles sobre todo para definir propiedades como resultado de una operación asíncrona, como son las llamadas ajax. Por ejemplo, si tuviéramos este json:

{

"data": "Awesome!"

}

Algo así no funcionaría por la asincronía de las llamadas ajax:

...

computed: {

greetingsSaturn: function() {

var xhr = new XMLHttpRequest();

xhr.onreadystatechange = function() {

if (xhr.readyState === 4 && xhr.status === 200) {

return JSON.parse(xhr.responseText).data;

}

};

xhr.open('GET', 'bar.json', true);

xhr.send();

}

},

...

Pero sí en un watch:

...

watch: {

greetings: function(newVal) {

var xhr = new XMLHttpRequest();

var self = this;

xhr.onreadystatechange = function() {

if (xhr.readyState === 4 && xhr.status === 200) {

self.greetings = JSON.parse(xhr.responseText).data;

}

};

xhr.open('GET', 'bar.json', true);

xhr.send();

}

}

...

Ciclo de vida

Al igual que sucede con los componentes de polymer, las instancias de vue.js también tienen un «ciclo de vida»,  un grupo de métodos que se invocan de forma automática en determinados momentos clave. En el caso de vue.js, estos métodos, que se conocen como hooks, ganchos, porque se enganchan en una fase de un proceso, son:

  • beforeCreate, antes de que se inicialice la instancia.
  • created, ya están listas la mayor parte de las cosas, como las propiedades computadas, pero aún no se ha engarzado la instancia con los nodos del DOM (la propiedad $el no está aún disponible).
  • beforeMount, justo antes de que se vaya a renderizar por primera vez.
  • mounted, equivaldría al ready() de jQuery, cuando ya está todo listo, incluidos los bindeos del DOM.
  • beforeUpdate, antes de que cambie una propiedad.
  • updated, después de que cambie una propiedad.
  • beforeDestroy, antes de que se destruya una instancia.
  • destroyed, cuando se destruye.

Por ejemplo:

mounted: function() {

console.log('todo listo');

},

updated: function() {

console.log('cambiado!');

}

Bueno, pues por hoy lo dejo aquí. He subido el código del ejemplo a un gist.

 

|| Tags: , ,

valoración de los lectores sobre vue js (2): propiedades

  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración negativa
  • 4 sobre 5 (1 votos)

¿Te ha parecido útil o interesante esta entrada?
dormido, valoración 1 nadapensativo, valoración 2 un poco sonrisa, valoración 3 a medias guiño, valoración 4 bastante aplauso, valoración 5 mucho

Tú opinión es muy importante, gracias por compartirla!

Los comentarios están cerrados.