Buscar..


Observaciones

camelCase <=> kebab-case

Al definir los nombres de sus props , recuerde siempre que los nombres de atributos HTML no distinguen entre mayúsculas y minúsculas. Eso significa que si define un prop en caso de camello en la definición de su componente ...

Vue.component('child', {
    props: ['myProp'],
    ...
});

... debes llamarlo en tu componente HTML como my-prop.

Pasando datos de padres a hijos con accesorios

En Vue.js, cada instancia de componente tiene su propio alcance aislado , lo que significa que si un componente principal tiene un componente secundario, el componente secundario tiene su propio alcance aislado y el componente primario tiene su propio alcance aislado.

Para cualquier aplicación de tamaño mediano a grande, seguir las convenciones de mejores prácticas previene muchos dolores de cabeza durante la fase de desarrollo y luego después del mantenimiento. Una de esas cosas a seguir es que evite hacer referencia / mutar datos primarios directamente desde el componente secundario . Entonces, ¿cómo hacemos referencia a los datos principales desde un componente secundario?

Cualquier información de los padres que se requiera en un componente secundario se debe pasar al niño como props de los padres.

Caso de uso : supongamos que tenemos una base de datos de usuarios con dos tablas, users y addresses con los siguientes campos:
tabla de users

nombre teléfono correo electrónico
John Mclane (1) 234 5678 9012 [email protected]
James Bond (44) 777 0007 0077 [email protected]

tabla de addresses

bloquear calle ciudad
Torres Nakatomi Broadway Nueva York
Casa mi6 Buckingham Road Londres

y queremos tener tres componentes para mostrar la información del usuario correspondiente en cualquier lugar de nuestra aplicación

user-component.js

export default{
    template:`<div class="user-component">
                <label for="name" class="form-control">Name: </label>  
                <input class="form-control input-sm" name="name" v-model="name">
                <contact-details :phone="phone" :email="email"></contact-details>
              </div>`,
    data(){
        return{
            name:'',
            phone:'',
            email:''
        }
    },
}  

contact-details.js

import Address from './address';
export default{
    template:`<div class="contact-details-component>
                <h4>Contact Details:</h4>
                <label for="phone" class="form-control">Phone: </label>  
                <input class="form-control input-sm" name="phone" v-model="phone">
                <label for="email" class="form-control">Email: </label>  
                <input class="form-control input-sm" name="email" v-model="email"> 
        
                <h4>Address:</h4>
                <address :address-type="addressType"></address>
                //see camelCase vs kebab-case explanation below
            </div>`,
    props:['phone', 'email'],
    data:(){
        return:{
            addressType:'Office'
        }
    },
    components:{Address}  
}  

dirección.js

export default{
    template:`<div class="address-component">
                <h6>{{addressType}}</h6>
                <label for="block" class="form-control">Block: </label>  
                <input class="form-control input-sm" name="block" v-model="block">
                <label for="street" class="form-control">Street: </label>  
                <input class="form-control input-sm" name="street" v-model="street">
                <label for="city" class="form-control">City: </label>  
                <input class="form-control input-sm" name="city" v-model="city">
             </div>`,
    props:{
        addressType:{
            required:true,
            type:String,
            default:'Office'
        },
    data(){
        return{
            block:'',
            street:'',
            city:''
        }
    }
}  

main.js

import Vue from 'vue';  
  
Vue.component('user-component', require'./user-component');  
Vue.component('contact-details', require'./contact-details');  

new Vue({
    el:'body'  
});  

index.html

...  
<body>
    <user-component></user-component>
        ...
</body>

Estamos mostrando los datos del phone y del email , que son propiedades del user-component de user-component en contact-details que no tienen datos del teléfono o correo electrónico.

Pasando datos como props

Entonces, dentro de user-component.js en la propiedad de la plantilla , donde incluimos el componente <contact-details> , pasamos el teléfono y los datos de correo electrónico de <user-component> (componente primario) a <contact-details> ( componente secundario) vinculándolo dinámicamente a los accesorios - :phone="phone" y :email="email que es igual que v-bind:phone="phone" y v-bind:email="email"

Puntales - Enlace dinámico

Dado que estamos vinculando dinámicamente las propuestas, cualquier cambio en el teléfono o correo electrónico dentro del componente principal, es decir, <user-component> se reflejará inmediatamente en el componente secundario, es decir, <contact-details> .

Accesorios - como literales

Sin embargo, si hubiéramos pasado los valores de teléfono y correo electrónico como valores literales de cadena como phone="(44) 777 0007 0077" email="[email protected]" entonces no reflejaría ningún cambio de datos que ocurra en el padre. componente.

Encuadernación unidireccional

De forma predeterminada, la dirección de los cambios es de arriba a abajo, es decir, cualquier cambio en los accesorios vinculados dinámicamente en el componente principal se propagará al componente secundario, pero cualquier cambio en los valores de prop en un componente secundario no se propagará al principal.

Por ejemplo: si dentro de <contact-details> cambiamos el correo electrónico de [email protected] a [email protected] , los datos de los padres, es decir, la propiedad de los datos del teléfono en <user-component> seguirán teniendo un valor de [email protected] .

Sin embargo, si cambiamos el valor del correo electrónico de [email protected] a [email protected] en el componente principal ( <user-component> en nuestro caso de uso), entonces el valor del correo electrónico en el componente secundario ( <contact-details> en nuestro caso de uso) cambiará a [email protected] automáticamente - el cambio en el padre se propagará instantáneamente al niño.

Enlace de dos vías

Si queremos un enlace bidireccional, debemos especificar explícitamente el enlace bidireccional como :email.sync="email" lugar de :email="email" . Ahora, si cambiamos el valor de prop en el componente secundario, el cambio también se reflejará en el componente principal.

En una aplicación de tamaño mediano a grande, cambiar el estado padre del estado hijo será muy difícil de detectar y controlar, especialmente durante la depuración: tenga cuidado .

No habrá ninguna opción .sync disponible en Vue.js 2.0. El enlace bidireccional para los accesorios está en desuso en Vue.js 2.0 .

Vinculante de una sola vez

También es posible definir un enlace explícito de una sola vez como :email.once="email , es más o menos similar a pasar un literal, porque cualquier cambio posterior en el valor de la propiedad principal no se propagará al elemento secundario.

ADVERTENCIA
Cuando se pasa un objeto o una matriz como prop, se pasarán SIEMPRE POR REFERENCIA , lo que significa que independientemente del tipo de enlace definido explícitamente :email.sync="email" o :email="email" o :email.once="email" , Si el correo electrónico es un objeto o una matriz en el principal, independientemente del tipo de enlace, cualquier cambio en el valor de prop dentro del componente secundario también afectará el valor en el primario.

Apoyos como Array

En el archivo contact-details.js hemos definido props:['phone', 'email'] como una matriz, lo cual está bien si no queremos un control detallado con props.

Apoyos como objeto

Si queremos un control más preciso sobre los accesorios, como

  • Si queremos definir qué tipo de valores son aceptables como prop.
  • ¿Cuál debería ser un valor por defecto para el prop
  • si un valor DEBE ser (obligatorio) para ser aprobado para la propuesta o es opcional

entonces necesitamos usar la notación de objetos para definir los accesorios, como hemos hecho en address.js .

Si estamos creando componentes reutilizables que pueden ser utilizados por otros desarrolladores en el equipo, entonces es una buena práctica definir objetos como objetos para que cualquiera que use el componente tenga una idea clara de cuál debería ser el tipo de datos y si Es obligatorio u opcional.

También se conoce como validación de accesorios . El tipo puede ser cualquiera de los siguientes constructores nativos:

  • Cuerda
  • Número
  • Booleano
  • Formación
  • Objeto
  • Función
  • o un constructor personalizado

Algunos ejemplos de validación de propiedades como tomados de http://vuejs.org/guide/components.html#Props

Vue.component('example', {
   props: {
       // basic type check (`null` means accept any type)
       propA: Number,
       // multiple possible types (1.0.21+)
       propM: [String, Number],
       // a required string
       propB: {
         type: String,
         required: true
       },
       // a number with default value
       propC: {
          type: Number,
          default: 100
       },
       // object/array defaults should be returned from a
       // factory function
       propD: {
          type: Object,
          default: function () {
             return { msg: 'hello' }
         }
       },
       // indicate this prop expects a two-way binding. will
       // raise a warning if binding type does not match.
       propE: {
          twoWay: true
       },
       // custom validator function
       propF: {
          validator: function (value) {
             return value > 10
          }
       },
       // coerce function (new in 1.0.12)
       // cast the value before setting it on the component
       propG: {
          coerce: function (val) {
            return val + '' // cast the value to string
          }
       },
       propH: {
          coerce: function (val) {
            return JSON.parse(val) // cast the value to Object
          }
       }
    }
});

camelCase vs kebab-case

Atributos HTML son entre mayúsculas y minúsculas, lo que significa que no puede diferenciar entre addresstype y addressType , por lo que cuando se utiliza nombres camelCase prop como atributos que necesitamos para utilizar su kebab de los casos equivalentes (guión) delimitado por:
addressType debe escribirse como address-type en el atributo HTML.

Apoyos dinámicos

Al igual que puede vincular los datos de una vista al modelo, también puede vincular accesorios utilizando la misma directiva v-bind para pasar información de los componentes principales a los secundarios.

JS

new Vue({
    el: '#example',
    data: {
        msg: 'hello world'
    }
});

Vue.component('child', {
    props: ['myMessage'],
    template: '<span>{{ myMessage }}</span>
});

HTML

<div id="example">
    <input v-model="msg" />
    <child v-bind:my-message="msg"></child>
    <!-- Shorthand ... <child :my-message="msg"></child> -->
</div>

Resultado

hello world

Pasando apoyos mientras usas Vue JSX

Tenemos un componente principal: importando un componente secundario en él pasaremos las propuestas a través de un atributo. Aquí el atributo es 'src' y también estamos pasando el 'src'.

ParentComponent.js

import ChildComponent from './ChildComponent';
export default {
    render(h, {props}) {
        const src = 'https://cdn-images-1.medium.com/max/800/1*AxRXW2j8qmGJixIYg7n6uw.jpeg';
        return (
           <ChildComponent src={src} />   
        );
    }
};

Y un componente infantil, donde tenemos que pasar props. Necesitamos especificar qué accesorios estamos pasando.

ChildComponent.js:

export default {
    props: ['src'],
    render(h, {props}) {
        return ( 
            <a href = {props.src} download = "myimage" >
                Click this link
            </a>
        );
    }
};


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow