- Aprender
-
Ecosistema
Ayuda
Herramientas
Librerías Oficiales
Noticias
Lista de Recursos
- Equipo
- Apoyar Vue
- Traducciones
Guía
Conocimientos Esenciales
- Instalación
- Introducción
- La instancia Vue
- Sintaxis de Template
- Propiedades Computadas y Observadores
- Enlace Clases y Estilos
- Renderización Condicional
- Renderizado de lista
- Manejo de eventos
- Binding en Formularios
- Conceptos Básicos de Componentes
Transiciones & Animaciones
- Efectos de Transición
Componentes en Profundidad
- Registro de Componente
- Propiedades
- Eventos personalizados
- Slots
- Componentes Dinámicos & Asíncronos
- Handling Edge Cases
- Transiciones de estado
Reusabilidad & Composición
- Mixins
- Directivas Personalizadas
- Funciones de renderizado & JSX
- Plugins
- Filtros
- Publicación en Producción
Herramientas
- Componentes de un Solo Archivo (Single File Components)
- Testing Unitario
- Soporte TypeScript
Escalando la Aplicación
- Enrutamiento
- Administración del Estado
- Renderizado del lado de Servidor
Funcionamiento Interno
- Reactividad en profundidad
Migraciones
- Migración desde Vue 1.x
- Migración desde Vue Router 0.7.x
- Migración de Vuex 0.6.x a 1.0
Meta Documentación
- Comparación con otros frameworks
- Únete a la comunidad Vue.js!
- Conozca al equipo
Renderizado de lista
Mapeando una matriz a elementos con v-for
Podemos usar la directiva v-for
para representar una lista de elementos basada en una matriz. La directiva v-for
requiere una sintaxis especial en forma de item in items
, donde los items
son la matriz de datos de origen y el item
es un alias para el elemento de matriz que se está iterando:
<ul id="example-1"> |
var example1 = new Vue({ |
Resultado:
- {{item.mensaje}}
Dentro de los bloques v-for
tenemos acceso completo a las propiedades del ámbito principal. v-for
también admite un segundo argumento opcional para el índice del elemento actual.
<ul id="example-2"> |
var example2 = new Vue({ |
Resultado:
- {{ mensajePadre }} - {{ index }} - {{ item.mensaje }}
También puede usar of
como delimitador en lugar de in
, de modo que esté más cerca de la sintaxis de JavaScript para los iteradores:
<div v-for="item of items"></div> |
v-for
con un Objeto
También puede usar v-for
para iterar a través de las propiedades de un objeto.
<ul id="v-for-object" class="demo"> |
new Vue({ |
Resultado:
- {{ value }}
También puede proporcionar un segundo argumento para la clave:
<div v-for="(value, key) in object"> |
Y otro para el índice:
<div v-for="(value, key, index) in object"> |
Al iterar sobre un objeto, el orden se basa en el orden de enumeración de claves de Object.keys()
, que no se garantiza que sea consistente en todas las implementaciones del motor de JavaScript.
key
Cuando Vue está actualizando una lista de elementos representados con v-for
, por defecto utiliza una estrategia de “parche in situ”. Si el orden de los elementos de datos ha cambiado, en lugar de mover los elementos DOM para que coincidan con el orden de los elementos, Vue aplicará parches a cada elemento en el lugar y se asegurará de que refleje lo que se debe representar en ese índice en particular. Esto es similar al comportamiento de track-by="$index"
en Vue 1.x.
Este modo predeterminado es eficiente, pero solo es adecuado cuando la salida de renderizado de su lista no se basa en el estado del componente secundario o el estado temporal de DOM (por ejemplo, valores de entrada de formulario).
Para proporcionar a Vue una sugerencia para que pueda rastrear la identidad de cada nodo y, por lo tanto, reutilizar y reordenar los elementos existentes, debe proporcionar un atributo key
único para cada elemento. Un valor ideal para key
sería el ID único de cada elemento. Este atributo especial es un equivalente aproximado a track-by
en 1.x, pero funciona como un atributo, por lo que necesita usar v-bind
para enlazarlo con valores dinámicos (usando el modo abreviado aquí):
<div v-for="item in items" :key="item.id"> |
Se recomienda proporcionar una key
con v-for
siempre que sea posible, a menos que el contenido DOM iterado sea simple, o esté confiando intencionalmente en el comportamiento predeterminado para obtener ganancias en el rendimiento.
Como Vue es un mecanismo genérico para identificar nodos, la key
también tiene otros usos que no están específicamente vinculados a v-for
, como veremos más adelante en la guía.
Detección de cambios en el Array
Métodos de Mutación
Vue envuelve los métodos de mutación de una matriz observada para que también activen las actualizaciones de vista. Los métodos envueltos son:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
Puede abrir la consola y probar con la matriz de items
de los ejemplos anteriores llamando a sus métodos de mutación. Por ejemplo: example1.items.push ({mensaje: 'Baz'})
.
Mutando un Array
Los métodos de mutación, como sugiere su nombre, mutan la matriz original a la que se llama. En comparación, también hay métodos no mutantes, p. Ej. filter()
, concat()
y slice()
, que no mutan la matriz original pero siempre devuelven una nueva matriz. Cuando trabaje con métodos no mutantes, puede reemplazar la matriz anterior por la nueva:
example1.items = example1.items.filter(function (item) { |
Podría pensar que esto hará que Vue elimine el DOM existente y vuelva a renderizar la lista completa; afortunadamente, ese no es el caso. Vue implementa algunas heurísticas inteligentes para maximizar la reutilización de elementos DOM, por lo tanto, reemplazar una matriz con otra matriz que contenga objetos superpuestos es una operación muy eficiente.
Advertencias
Debido a las limitaciones en JavaScript, Vue no puede detectar los siguientes cambios en una matriz:
Cuando configura directamente un elemento con el índice, por ejemplo,
vm.items[indexOfItem] = newValue
Cuando modifica la longitud de la matriz, por ejemplo,
vm.items.length = newLength
Por ejemplo:
var vm = new Vue({ |
Para superar la advertencia 1, ambos de los siguientes lograrán lo mismo que vm.items[indexOfItem] = newValue
, pero también activarán actualizaciones de estado en el sistema de reactividad:
// Vue.set |
// Array.prototype.splice |
También puede usar el método de instancia vm.$Set
, que es un alias para el Vue.set
global:
vm.$set(vm.items, indexOfItem, newValue) |
Para tratar con la advertencia 2, puede usar splice
:
vm.items.splice(newLength) |
Advertencias con la Detección de Cambios en Objetos
Una vez más, debido a las limitaciones del JavaScript moderno, Vue no puede detectar la adición o eliminación de propiedades. Por ejemplo:
var vm = new Vue({ |
Vue no permite agregar dinámicamente nuevas propiedades reactivas a nivel de raíz a una instancia ya creada. Sin embargo, es posible agregar propiedades reactivas a un objeto anidado usando el método Vue.set (objeto, clave, valor)
. Por ejemplo, dado:
var vm = new Vue({ |
Podría agregar una nueva propiedad de edad
al objeto de userProfile
anidado con:
Vue.set(vm.userProfile, 'edad', 27) |
También puede usar el método de instancia vm. $Set
, que es un alias para el Vue.set
global:
vm.$set(vm.userProfile, 'edad', 27) |
En ocasiones, es posible que desee asignar varias propiedades nuevas a un objeto existente, por ejemplo, utilizando Object.assign()
o _.extend()
. En tales casos, debe crear un objeto nuevo con propiedades de ambos objetos. Así que en lugar de:
Object.assign(vm.userProfile, { |
Puedria agregar nuevas propiedades reactivas con:
vm.userProfile = Object.assign({}, vm.userProfile, { |
Mostrando Resultados Filtrados/Ordenados
A veces, queremos mostrar una versión filtrada u ordenada de una matriz sin mutar o restablecer los datos originales. En este caso, puede crear una propiedad computada que devuelva la matriz filtrada u ordenada.
Por ejemplo:
<li v-for="n in numerosImpares">{{ n }}</li> |
data: { |
En situaciones donde las propiedades computadas no son factibles (por ejemplo, dentro de los bucles v-for
anidados), puede usar un método:
<li v-for="n in even(numeros)">{{ n }}</li> |
data: { |
v-for
con un Rango
v-for
también puede tomar un entero. En este caso repetirá la plantilla muchas veces.
<div> |
Resultado:
v-for
en un <template>
De forma similar a la plantilla v-if
, también puede usar una etiqueta <template>
con v-for
para renderizar un bloque de varios elementos. Por ejemplo:
<ul> |
v-for
con v-if
Tenga en cuenta que no se recomienda usar v-if
y v-for
juntos. Consulte la guía de estilo para más detalles.
Cuando existen en el mismo nodo, v-for
tiene una prioridad más alta que v-if
. Eso significa que el v-if
se ejecutará en cada iteración del bucle por separado. Esto puede ser útil cuando desea representar nodos solo para algunos elementos, como a continuación:
<li v-for="todo in todos" v-if="!todo.isComplete"> |
Lo anterior hace que los todos que no estén completos, se rendericen.
Si, por el contrario, su intención es omitir condicionalmente la ejecución del bucle, puede colocar el v-if
en un elemento de envoltura (o <template>
). Por ejemplo:
<ul v-if="todos.length"> |
v-for
con un Componente
Esta sección asume el conocimiento de Componentes. Siéntase libre de saltearlo y volver más tarde.
Puede usar v-for
directamente en un componente personalizado, como cualquier elemento normal:
<my-component v-for="item in items" :key="item.id"></my-component> |
En 2.2.0+, cuando se usa
v-for
con un componente, ahora se requiere unakey
.
Sin embargo, esto no pasará automáticamente ningún dato al componente, porque los componentes tienen sus propios ámbitos aislados. Para pasar los datos iterados al componente, también debemos usar props:
<my-component |
La razón para no inyectar automáticamente el item
en el componente es porque hace que el componente esté estrechamente acoplado a cómo funciona v-for
. Ser explícito acerca de dónde provienen sus datos hace que el componente sea reutilizable en otras situaciones.
Aquí hay un ejemplo completo de una lista de tareas simple:
<div id="todo-list-example"> |
Note el atributo is = "todo-item"
. Esto es necesario en las plantillas DOM, porque solo un elemento <li>
es válido dentro de un <ul>
. Hace lo mismo que <todo-item>
, pero funciona alrededor de un error potencial de análisis del navegador. Ver las advertencias de análisis de plantillas DOM aprender más.
.component('todo-item', { |