- 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
Conceptos Básicos de Componentes
Ejemplo base
Aquí un ejemplo de un componente Vue:
// Definir un nuevo componente llamado button-counter |
Los componentes son instancias reutilizables de Vue con un nombre: en este caso, <button-counter>
. Podemos usar este componente como un elemento personalizado dentro de una instancia de Vue raíz creada con new Vue
:
<div id="components-demo"> |
new Vue({ el: '#components-demo' }) |
Dado que los componentes son instancias reutilizables de Vue, aceptan las mismas opciones que new Vue
, como data
, computed
, watch
, methods
, y hooks de ciclo de vida. Las únicas excepciones son algunas opciones específicas de la raíz como el
.
Reutilizando Componentes
Los componentes se pueden reutilizar tantas veces como se desee:
<div id="components-demo"> |
Tenga en cuenta que al hacer clic en los botones, cada uno mantiene su propio count
por separado. Esto se debe a que cada vez que utiliza un componente, se crea una nueva instancia del mismo.
data
Debe ser una función
Cuando definimos el componente <button-counter>
, es posible que haya notado que data
no devuelve directamente un objeto, como este:
data: { |
En lugar de eso, la opción data
de un componente debe ser una función, de modo que cada instancia pueda mantener una copia independiente del objeto de datos devuelto:
data: function () { |
Si Vue no tuviera esta regla, hacer clic en un botón afectaría los datos de todas las demás instancias, como a continuación:
Organización de Componentes
Es común que una aplicación se organice en un árbol de componentes anidados:
Por ejemplo, puede tener componentes para un encabezado, una barra lateral y un área de contenido, cada uno de los cuales generalmente contiene otros componentes para enlaces de navegación, publicaciones de blog, etc.
Para usar estos componentes en templates, deben registrarse para que Vue los conozca. Existen dos tipos de registro de componentes: global y local. Hasta ahora, solo hemos registrado componentes globalmente, usando Vue.component
:
Vue.component('my-component-name', { |
Los componentes registrados globalmente se pueden usar en el template de cualquier instancia de Vue raíz (new Vue
) creada posteriormente, e incluso dentro de todos los subcomponentes del árbol de componentes de esa instancia de Vue.
Eso es todo lo que necesita saber sobre el registro por ahora, pero una vez que haya terminado de leer esta página y se sienta cómodo con su contenido, le recomendamos volver más tarde para leer la guía completa de Registro de Componentes.
Pasando datos a componentes secundarios con Props
Anteriormente, mencionamos la creación de un componente para publicaciones de blog. El problema es que ese componente no será útil a menos que puedas pasarle datos, como el título y el contenido de la publicación específica que queremos mostrar. Ahí es donde entran las props.
Las props son atributos personalizados que usted puede registrar en un componente. Cuando se pasa un valor a un atributo prop, se convierte en una propiedad en esa instancia de componente. Para pasar un título a nuestro componente de publicación de blog, podemos incluirlo en la lista de props que este componente acepta, usando la opción props
:
Vue.component('blog-post', { |
Un componente puede tener tantas props como se desee, y se puede pasar cualquier valor a cualquier prop de forma predeterminada. En el template anterior, verá que podemos acceder a este valor en la instancia del componente, al igual que con data
.
Una vez que se registra un prop, puede pasarle datos como un atributo personalizado, de la siguiente manera:
<blog-post title="Mi viaje con Vue"></blog-post> |
En una aplicación típica, sin embargo, es probable que tenga un array de post en data
:
new Vue({ |
Entonces querrá renderizar un componente para cada uno:
<blog-post |
Arriba, verá que podemos usar v-bind
para pasar propiedades dinámicamente. Esto es especialmente útil cuando no se conoce el contenido exacto que se va a renderizar con anticipación, como cuando se obtienen posts de una API.
Esto es todo lo que necesita saber sobre propiedades por ahora, pero una vez que haya terminado de leer esta página y se sienta cómodo con su contenido, le recomendamos volver más tarde para leer la guía completa de Propiedades.
Un elemento de una sola raíz
Al crear un componente <blog-post>
, su plantilla eventualmente no contendrá más que solo el título:
<h3>{{ title }}</h3> |
Como mínimo, querrá incluir el contenido del post:
<h3>{{ title }}</h3> |
Sin embargo, si intenta esto en su plantilla, Vue mostrará un error, explicando que cada componente debe tener un solo elemento raíz. Puede corregir este error envolviendo la plantilla en un elemento principal de la siguiente manera:
<div class="blog-post"> |
A medida que nuestro componente crezca, es probable que no solo necesitemos el título y el contenido de una publicación, sino también la fecha de publicación, los comentarios y más. Definir una propiedad para cada pieza de información relacionada podría volverse muy molesto:
<blog-post |
Por lo tanto, este podría ser un buen momento para refactorizar el componente <blog-post>
para que acepte una única propiedad
post:
<blog-post |
Vue.component('blog-post', { |
El ejemplo anterior y algunos que veremos más adelante, utilizan Plantillas de cadena de texto de JavaScript para hacer que las plantillas multilínea sean más legibles. Internet Explorer (IE) no las admite, por lo tanto, si debe ser compatible con IE y no está transpilando (por ejemplo, con Babel o TypeScript), usa escapes de nueva línea en su lugar
.Ahora, cada vez que se agreguen nuevas propiedadaes al objeto post
, estarán automáticamente disponible dentro de <blog-post>
.
Enviando mensajes a componentes padre con eventos
A medida que desarrollamos nuestro componente <blog-post>
, es posible que algunas funciones requieran la comunicación hacia el componente padre. Por ejemplo, podemos decidir incluir una función de accesibilidad para ampliar el texto de las publicaciones del blog, dejando el resto de la página en su tamaño por defecto:
En el padre, podemos admitir esta función agregando una propiedad postFontSize
en data
:
new Vue({ |
Esta propiedad puede ser usada en la plantilla para controlar el tamaño de la fuente de todas las publicaciones del blog:
<div id="blog-posts-events-demo"> |
Ahora agreguemos un botón para ampliar el texto justo antes del contenido de cada publicación:
Vue.component('blog-post', { |
El problema es que este botón no hace nada:
<button> |
Cuando hacemos clic en el botón, debemos comunicar al componente padre que debe agrandar el texto de todas las publicaciones. Afortunadamente, las instancias de Vue proporcionan un sistema de eventos personalizados para resolver este problema. Para emitir un evento a los padres, podemos llamar al método $emit
, pasando el nombre del evento:
<button v-on:click="$emit('enlarge-text')"> |
Luego, en nuestro blog post, podemos escuchar este evento con v-on
, tal como lo haríamos con un evento DOM nativo:
<blog-post |
Emitiendo un valor con un Evento
A veces es útil emitir un valor específico con un evento. Por ejemplo, podemos querer que el componente <blog-post>
se encargue de cuánto agrandar el texto. En esos casos, podemos usar el segundo parámetro de $emit
para proporcionar este valor:
<button v-on:click="$emit('enlarge-text', 0.1)"> |
Luego, cuando escuchamos el evento en el componente padre, podemos acceder al valor del evento emitido con $event
:
<blog-post |
O, si el controlador de eventos es un método:
<blog-post |
Entonces el valor se pasará como el primer parámetro de ese método:
methods: { |
Usando v-model
en Componentes
Los eventos personalizados también se pueden usar para crear inputs personalizados que funcionan con v-model
. Recuerde que:
<input v-model="searchText"> |
hace lo mismo que:
<input |
Cuando se usa en un componente, v-model
en su lugar hace esto:
<custom-input |
Para que esto realmente funcione, el <input>
dentro del componente debe:
- Enlazar el atributo
value
a una propiedadvalue
- En el
input
, emitir su propio eventoinput
personalizado con el nuevo valor
Aquí está en acción:
Vue.component('custom-input', { |
Ahora v-model
debería funcionar perfectamente con este componente:
<custom-input v-model="searchText"></custom-input> |
Por ahora, eso es todo lo que necesita saber sobre los eventos de componentes personalizados, pero una vez que haya terminado de leer esta página y se sienta cómodo con su contenido, le recomendamos volver más tarde para leer la guía completa sobre Eventos Personalizados.
Distribución de contenido con Slots
Al igual que con los elementos HTML, a menudo es útil poder pasar contenido a un componente, como este:
<alert-box> |
Lo que podría renderizar algo como:
Afortunadamente, esta tarea se hace muy simple con el elemento personalizado <slot>
de Vue:
Vue.component('alert-box', { |
Como verá más arriba, solo agregamos la ranura a la que queremos que el contenido vaya – y eso es todo. Hemos terminado!
Eso es todo lo que necesita saber acerca de slots por ahora, pero una vez que haya terminado de leer esta página y se sienta cómodo con su contenido, le recomendamos que regrese más tarde para leer la guía completa de Slots.
Componentes dinámicos
A veces, es útil cambiar dinámicamente entre componentes, como en una interfaz con pestañas:
Lo anterior es posible gracias al elemento <component>
de Vue con el atributo especial is
:
<!-- El componente cambia cuando currentTabComponent cambia --> |
En el ejemplo anterior, currentTabComponent
puede contener:
- el nombre de un componente registrado, o
- un objeto de opciones de un componente
Vea este fiddle para experimentar con el código completo, o esta versión para un ejemplo de enlace o binding al objeto de opciones de un componente, en lugar de su nombre registrado.
Eso es todo lo que necesita saber sobre los componentes dinámicos por ahora, pero una vez que haya terminado de leer esta página y se sienta cómodo con su contenido, le recomendamos volver más tarde para leer la guía completa sobre Componentes Dinámicos y Asíncronos.
Casos especiales de análisis de plantillas DOM.
Algunos elementos HTML, como <ul>
, <ol>
, <table>
y <select>
tienen restricciones sobre qué elementos pueden aparecer dentro de ellos, y algunos elementos como <li>
, <tr>
y <option>
solo pueden aparecer dentro de ciertos otros elementos.
Esto conducirá a problemas cuando se utilizan componentes con elementos que tienen tales restricciones. Por ejemplo:
<table> |
El componente personalizado <blog-post-row>
se colocará como contenido no válido, lo que provocará errores en el resultado final. Afortunadamente, el atributo especial is
ofrece una solución alternativa:
<table> |
Debe tenerse en cuenta que esta limitación no se aplica si está utilizando plantillas de cadenas de texto de una de las siguientes fuentes:
- Plantillas de cadenas de texto (ej:
template: '...'
) - Componentes de un solo archivo (
.vue
) <script type="text/x-template">
Eso es todo lo que necesita saber sobre los casos especiales de análisis de plantillas DOM por ahora, y en realidad, el final de los aspectos esenciales de Vue. ¡Felicidades! Todavía hay más que aprender, pero primero, recomendamos tomar un descanso para practicar con Vue usted mismo y construir algo divertido.
Una vez que se sienta cómodo con el conocimiento que acaba de digerir, le recomendamos que regrese para leer la guía completa de Componentes Dinámicos y Asíncronos, así como las otras páginas en la sección Componentes en Profundidad de la barra lateral.