en VueJS

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.

Deja un comentario