# Props

Esta página asume que usted ya ha leído Básicos de Componentes. Léalo primero si usted es nuevo con componentes.

Aprender cómo funciona las _props_ de componente con una lección gratis en Vue School

# Tipos de Prop

Hasta ahora, solo hemos visto las props listadas como una matriz de cadenas de caracteres:

props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
1

Sin embargo, por lo general, querrá que cada prop sea un tipo específico de valor. En estos casos, puede enumerar las props como un objeto, donde los nombres y valores de las propiedades de este objeto contienen los nombres y tipos de las props, respectivamente:

props: {
  title: String,
  likes: Number,
  isPublished: Boolean,
  commentIds: Array,
  author: Object,
  callback: Function,
  contactsPromise: Promise // o cualquier otro constructor
}
1
2
3
4
5
6
7
8
9

Esto no solo documenta su componente, sino que también advertirá a los usuarios en la consola de JavaScript del navegador si se está pasando el tipo incorrecto. Aprenderá mucho más sobre verificaciones de tipos y otras validaciones de props más adelante en esta página.

# Pasar props estáticas o dinámicas

Hasta ahora, ha visto que las props pasaban un valor estático, como en:

<blog-post title="My journey with Vue"></blog-post>
1

También ha visto props asignadas dinámicamente con v-bind o su abreviatura, el carácter :, como en:

<!-- Asigna dinámicamente el valor de una variable -->
<blog-post :title="post.title"></blog-post>

<!-- Asigna dinámicamente el valor de una expresión compleja. -->
<blog-post :title="post.title + ' por ' + post.author.name"></blog-post>
1
2
3
4
5

En los dos ejemplos anteriores, pasamos valores de cadena de caracteres, pero cualquier tipo de valor se puede pasar a una prop.

# Pasar un número

<!-- Aunque `42` es estático, necesitamos v-bind para decirle a Vue que -->
<!-- es una expresión de JavaScript en vez de una cadena de caracteres. -->
<blog-post :likes="42"></blog-post>

<!-- Asigna dinámicamente el valor de una variable. -->
<blog-post :likes="post.likes"></blog-post>
1
2
3
4
5
6

# Pasar un booleano

<!-- Incluir la prop sin valor implicará `true` -->
<!-- Si no asigna Boolean al tipo de is-published en props, será una cadena de caracteres vacía en vez del valor "true" -->
<blog-post is-published></blog-post>

<!-- Aunque `false` es estático, necesitamos v-bind para decirle a Vue que -->
<!-- es una expresión de JavaScript en vez de una cadena de caracteres. -->
<blog-post :is-published="false"></blog-post>

<!-- Asigna dinámicamente el valor de una variable. -->
<blog-post :is-published="post.isPublished"></blog-post>
1
2
3
4
5
6
7
8
9
10

# Pasar una matriz

<!-- Aunque la matriz es estático, necesitamos v-bind para decirle a Vue que -->
<!-- es una expresión de JavaScript en vez de una cadena de caracteres. -->
<blog-post :comment-ids="[234, 266, 273]"></blog-post>

<!-- Asigna dinámicamente el valor de una variable. -->
<blog-post :comment-ids="post.commentIds"></blog-post>
1
2
3
4
5
6

# Pasar un objeto

<!-- Aunque el objeto es estático, necesitamos v-bind para decirle a Vue que -->
<!-- es una expresión de JavaScript en vez de una cadena de caracteres. -->
<blog-post
  :author="{
    name: 'Veronica',
    company: 'Veridian Dynamics'
  }"
></blog-post>

<!-- Asigna dinámicamente el valor de una variable. -->
<blog-post :author="post.author"></blog-post>
1
2
3
4
5
6
7
8
9
10
11

# Pasar las propiedades de un objeto

Si desea pasar todas las propiedades de un objeto como props, puede usar v-bind sin un argumento (v-bind en lugar de :prop-name). Por ejemplo, dado un objeto post:

post: {
  id: 1,
  title: 'Mi viaje con vue'
}
1
2
3
4

La siguiente plantilla:

<blog-post v-bind="post"></blog-post>
1

Será equivalente a:

<blog-post v-bind:id="post.id" v-bind:title="post.title"></blog-post>
1

# Flujo de datos de una sola dirección

Todas las props forman una vinculación de una sola dirección entre la propiedad del hijo y la de su padre: cuando la propiedad del padre se actualice, fluirá hacia el hijo, pero no al revés. Esto evita que los componentes secundarios muten accidentalmente el estado de los padres, lo que puede hacer que el flujo de datos de su aplicación sean más difíciles de entender.

Además, cada vez que se actualice el componente padre, todas las props del componente secundario se actualizarán con el último valor. Esto significa que usted no debe intentar mutar una prop dentro de un componente secundario. Si lo hace, Vue le advertirá en la consola.

Normalmente hay dos casos en los que es tentador mutar una prop:

  1. La prop es utilizado para pasar un valor inicial; el componente secundario desea utilizarlo como una local propiedad de datos más adelante. En este caso, es mejor definir una local propiedad de datos que utiliza la prop como su valor inicial:
props: ['initialCounter'],
data() {
  return {
    counter: this.initialCounter
  }
}
1
2
3
4
5
6
  1. La prop se pasa como un valor crudo que debe transformarse. En este caso, es mejor definir una propiedad computada utilizando el valor de la prop:
props: ['size'],
computed: {
  normalizedSize() {
    return this.size.trim().toLowerCase()
  }
}
1
2
3
4
5
6

Warning

Tenga en cuenta que los objetos y las matrices en JavaScript se pasan por referencia, por lo que si la prop es una matriz u objeto, mutar el objeto o la matriz mismo dentro del componente secundario afectará el estado del padre y Vue no es capaz de advertirle contra esto. Como regla general, debería evitar mutar cualquiera prop, incluso objetos y matrices debido a que hacerlo ignora la vinculación de dato de una sola dirección y podría generar resultados no deseados.

# Validación de props

Los componentes pueden especificar requisitos para sus props, como los tipos que ya ha visto. Si no se cumple un requisito, Vue le avisará en la consola de JavaScript del navegador. Esto es especialmente útil cuando se desarrolla un componente que está destinado a ser utilizado por otros.

Para especificar validaciones de props, puede proporcionar un objeto con requisitos de validación al valor de props, en lugar de una matriz de cadenas de caracteres. Por ejemplo:

app.component('my-component', {
  props: {
    // Comprobación de tipo básico (`null` y `undefined` coincide con cualquier tipo)
    propA: Number,
    // Múltiples tipos posibles
    propB: [String, Number],
    // se requiere cadena de caracteres
    propC: {
      type: String,
      required: true
    },
    // Número con un valor por defecto
    propD: {
      type: Number,
      default: 100
    },
    // Objeto con un valor por defecto
    propE: {
      type: Object,
      // Los valores por defecto del objeto o matriz deben retornarse desde
      // una función de fábrica
      default() {
        return { message: 'hello' }
      }
    },
    // Función de validación personalizada
    propF: {
      validator(value) {
        // El valor debe coincidir con una de estas cadenas de caracteres
        return ['success', 'warning', 'danger'].includes(value)
      }
    },
    // Función con un valor por defecto
    propG: {
      type: Function,
      // A diferencia de los valores por defecto de objetos o matrices, esta no es una función de fábrica - esta es una función para servirse como un valor por defecto.
      default() {
        return 'Función por defecto'
      }
    }
  }
})
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
30
31
32
33
34
35
36
37
38
39
40
41
42

Cuando falla la validación de prop, Vue producirá una advertencia en la consola (si se utiliza la compilación de desarrollo).

Note

Tenga en cuenta que las props se validan antes de que se cree una instancia de componente, por lo que las propiedades de la instancia (p. ej. data, computed, etc.) no estarán disponibles dentro de las funciones default o validator.

# Validación de Tipos

La opción type puede ser uno de los siguientes constructores nativos:

  • String
  • Number
  • Boolean
  • Array
  • Object
  • Date
  • Function
  • Symbol

Además, type también puede ser una función constructora personalizada y la aserción se realizará con una comprobación de instanceof. Por ejemplo, dada la siguiente función constructora:

function Person(firstName, lastName) {
  this.firstName = firstName
  this.lastName = lastName
}
1
2
3
4

Usted podría utilizar:

app.component('blog-post', {
  props: {
    author: Person
  }
})
1
2
3
4
5

para validar que el valor de la prop author fue creado con new Person.

# Casos de Props (camelCase versus kebab-case)

Los nombres de atributos HTML no distinguen entre mayúsculas y minúsculas, por lo que los navegadores interpretarán los caracteres en mayúscula como en minúscula. Eso significa que cuando utiliza plantillas del DOM, los nombres de props de camelCase necesitan utilizar sus equivalentes de kebab-case (delimitados por guiones):

const app = Vue.createApp({})

app.component('blog-post', {
  // _camelCase_ en JavaScript
  props: ['postTitle'],
  template: '<h3>{{ postTitle }}</h3>'
})
1
2
3
4
5
6
7
<!-- kebab-case en HTML -->
<blog-post post-title="hello!"></blog-post>
1
2

Otra vez, si está utilizando plantillas de cadenas de caracteres, esta limitación no se aplica.