Vamos a explicar qué son los componentes y lo aplicaremos en el ejemplo hecho en el post #2.
Los componentes es una de las características más poderosas de Vue.js, según dice en la documentación. Con los componentes podemos dividir nuestra aplicación en diferentes trozos más pequeños, los cuales pueden ser totalmente independientes o que dependan de otros (componentes hijos), por tanto, un componente sería un trozo de código que contiene el código necesario para una parte específica de nuestra aplicación. Los componentes pueden ser totalmente reutilizables en diferentes partes de nuestra aplicación o en otras aplicaciones (como el que utilizamos en el post anterior) y esto nos permitirá no tener que repetir código innecesariamente.
Vamos a por el ejemplo y así entender mejor qué son.
Vamos a dividir el ejemplo de la lista de tareas en tres componentes. Los tres componentes serán:
- task-item: será el componente que contenga la tarea en sí. El título, el checkbox y el botón de eliminar.
- task-list: será el componente que contendrá la lista de tareas, por tanto, contendrá una lista de componentes task-item.
- task: que será el componente principal que contendrá el input, el mensaje que avisa de que no hay tareas y el componente task-list.
Crear componente tasks
Primero de todo vamos a crear el HTML del componente padre:
1 2 3 4 5 6 7 8 9 10 11 |
<div id="app"> <tasks></tasks> </div> <template id='tasks-template'> <div> <input type="text" placeholder='New task' v-model='newTask' @keyup.enter='addNewTask'> <p v-show='!tasks.length'>No tasks!</p> <task-list :tasks='tasks'></task-list> </div> </template> |
El JS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
Vue.component('tasks', { template: '#tasks-template', components: { 'task-list' : componentTaskList }, data: function () { return { newTask: '', tasks: [ { title: 'Tarea 1', done: false}, { title: 'Tarea 2', done: true} ] } }, methods: { addNewTask: function() { var newTaskObj = { title: this.newTask, done: false } this.tasks.push(newTaskObj); this.newTask = ''; } } }) new Vue({ el: '#app' }); |
Creamos un template con el id task-template y lo incluimos desde el JS con la propiedad template.
Para crear un componente se puede hacer de varias maneras, este componente lo vamos a declarar como un componente global. Los demás los declararemos como componentes locales, es decir, componentes que dependen de otros. Le hemos puesto de nombre tasks, por tanto, para llamarlo tendremos que poner un tag HTML que se llame <tasks></tasks> como puedes ver en el HTML.
Para añadir los componentes hijos tendremos que añadirlos en la propiedad components, indicando el nombre del tag y la variable con el código del componente. Este componente, tiene un hijo, que crearemos ahora, que se se llama task-list. Cuando se llama al componente task-list en el HTML, se le pasa por un atributo ( :tasks='tasks' ) la lista de tareas para que pueda acceder este componente a esos datos, ya que son datos que son del componente padre y si se quiere que un componente hijo pueda acceder a esos datos se hace así.
Crear componente task-list
Añadimos el template HTML:
1 2 3 4 5 |
<template id='task-list-template'> <ul id="list-tasks"> <task-item v-for="(task, index) in tasks" :task='task' :key="index" @click-remove-task='removeTask'></task-item> </ul> </template> |
Se hace un bucle de la lista de tareas sobre el componente task-item y se le pasa la tarea ( :task='task' ) para que pueda mostrarla. También, hemos añadido otro atributo ( @click-remove-task='removeTask' ) que es un evento para poder eliminar tareas, se lanzará cuando hagamos click al botón de eliminar (se lanza desde el componente task-item) y ejecutará la función removeTask. Esto es así, ya que queremos acceder desde el hijo a datos que tiene el padre.
Añadimos el JS:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
var componentTaskList = { template: '#task-list-template', components: { 'task-item' : componentTaskItem }, props: ['tasks'], methods: { removeTask: function(task) { var index = this.tasks.indexOf(task); this.tasks.splice(index, 1); } } } |
Como he dicho anteriormente, al ser un componente local, se declara así, para después poderlo añadir en el componente padre.
En el JS, se añade el template, el componente hijo que será el task-item y se recogen las propiedades en props, que en este caso es el array con la lista de tareas. Los métodos continúan igual, simplemente lo hemos cambiado de sitio.
Crear componente task-item
Creamos el template para el componente:
1 2 3 4 5 6 7 |
<template id='task-item-template'> <li> <input type="checkbox" v-model='task.done'> <span v-bind:class="{'task-done' : task.done}">{{ task.title }}</span> <button v-on:click='onClickRemove(task)'>x</button> </li> </template> |
Creamos un template con id igual a task-item-template.
Añadimos el JS:
1 2 3 4 5 6 7 8 9 |
var componentTaskItem = { template: '#task-item-template', props: ['task'], methods: { onClickRemove: function (task) { this.$emit('click-remove-task', task) } } } |
En el JS, se añade el template y se recogen las propiedades en props, que en este caso serán los datos de cada tarea. En los métodos, hemos declarado uno nuevo, que lo que hace es cuando le hacemos click al botón de eliminar, lanza el evento click-remove-task con la tarea que queremos eliminar, para que después el evento la recoja, ejecute la función removeTask y la elimine.
En esta entrada, hemos tratado muchísimas cosas, espero que quede todo claro y os sirva.
See the Pen Vue.js 2 #4 by vreaxe (@vreaxe) on CodePen.
-