Recherche…


Remarques

camelCase <=> kebab-case

Lors de la définition des noms de vos props , rappelez-vous toujours que les noms d'attributs HTML sont insensibles à la casse. Cela signifie que si vous définissez un prop dans un cas camel dans la définition de votre composant ...

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

... vous devez l'appeler dans votre composant HTML en tant que ma-prop.

Transmission de données de parent à enfant avec des accessoires

Dans Vue.js, chaque instance de composant a sa propre étendue isolée , ce qui signifie que si un composant parent a un composant enfant, le composant enfant a sa propre étendue isolée et le composant parent a sa propre étendue isolée.

Pour toute application de taille moyenne à grande, le respect des conventions de bonnes pratiques évite de nombreux problèmes lors de la phase de développement, puis après la maintenance. Une des choses à suivre est d' éviter de référencer ou de muter des données parent directement à partir du composant enfant . Alors, comment pouvons-nous référencer les données parent à partir d'un composant enfant?

Toutes les données parentales requises dans un composant enfant doivent être transmises à l'enfant en tant que props du parent.

Cas d'utilisation : Supposons que nous ayons une base de données utilisateur avec deux users et addresses tables avec les champs suivants:
Table d' users

prénom téléphone email
John Mclane (1) 234 5678 9012 [email protected]
James Bond (44) 777 0007 0077 [email protected]

Table d' addresses

bloc rue ville
Tours Nakatomi Broadway New York
Maison Mi6 Buckingham Road Londres

et nous voulons avoir trois composants pour afficher les informations utilisateur correspondantes n'importe où dans notre application

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}  
}  

address.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>

Nous affichons les données de phone et de email , qui sont les propriétés du user-component dans contact-details qui ne contiennent pas de données de téléphone ou de courrier électronique.

Transmettre des données comme accessoires

Donc, dans le user-component.js de la propriété template , où nous incluons le composant <contact-details> , nous transmettons le téléphone et les données de messagerie de <user-component> (composant parent) à <contact-details> ( composant enfant) en le liant dynamiquement aux accessoires - :phone="phone" et :email="email identique à v-bind:phone="phone" et v-bind:email="email"

Props - Reliure dynamique

Comme nous lions dynamiquement les accessoires, tout changement de téléphone ou de courrier électronique dans le composant parent, à savoir <user-component> sera immédiatement répercuté dans le composant enfant, c. <contact-details> d. <contact-details> .

Props - comme littéraux

Cependant, si nous avions passé les valeurs de téléphone et de courrier électronique sous la forme de valeurs littérales de type chaîne de caractères telles que phone="(44) 777 0007 0077" email="[email protected]" cela ne refléterait aucune modification de données composant.

Reliure à sens unique

Par défaut, la direction des modifications est de haut en bas, c'est-à-dire que toute modification des propriétés liées dynamiquement dans le composant parent se propagera au composant enfant, mais toute modification des valeurs de prop dans un composant enfant ne se propagera pas au parent.

Par exemple: si à l' intérieur des <contact-details> nous changeons l'e - mail de [email protected] à [email protected] , la propriété des données de téléphone données parent à savoir dans <user-component> contiendra encore une valeur de [email protected] .

Cependant, si nous changeons la valeur de l'email de [email protected] à [email protected] dans le composant parent ( <user-component> dans notre cas d'utilisation), alors la valeur de l'email dans le composant enfant ( <contact-details> dans notre cas d'utilisation) changera automatiquement pour [email protected] - le changement de parent est instantanément transmis à l'enfant.

Reliure bidirectionnelle

Si nous voulons une liaison bidirectionnelle, nous devons explicitement spécifier une liaison bidirectionnelle comme :email.sync="email" au lieu de :email="email" . Maintenant, si nous modifions la valeur de prop dans le composant enfant, la modification sera également répercutée dans le composant parent.

Dans une application de taille moyenne à grande, il sera très difficile de détecter l'état parent à partir de l'état enfant et de le suivre, en particulier lors du débogage. - Soyez prudent .

Il n'y aura pas d'option .sync disponible dans Vue.js 2.0. La liaison bidirectionnelle pour les accessoires est obsolète dans Vue.js 2.0 .

Liaison ponctuelle

Il est également possible de définir une liaison explicite unique comme :email.once="email , il est plus ou moins similaire à passer un littéral, car toute modification ultérieure de la valeur de la propriété parent ne se propagera pas à l'enfant.

CAVEAT
Lorsque Object ou Array est passé en prop, ils sont TOUJOURS PASSÉS PAR REFERENCE , ce qui signifie quel que soit le type de liaison explicitement défini :email.sync="email" ou :email="email" ou :email.once="email" , Si email est un objet ou un tableau dans le parent, quel que soit le type de liaison, toute modification de la valeur de prop dans le composant enfant affectera également la valeur du parent.

Les accessoires comme tableau

Dans le fichier contact-details.js , nous avons défini des props:['phone', 'email'] comme un tableau, ce qui est bien si nous ne voulons pas un contrôle fin avec des accessoires.

Les accessoires comme objet

Si nous voulons un contrôle plus fin des accessoires, comme

  • si nous voulons définir quel type de valeurs sont acceptables comme prop
  • quelle devrait être une valeur par défaut pour le prop
  • si une valeur DOIT (obligatoire) être passée pour le prop ou est-elle facultative?

alors nous devons utiliser la notation d'objet pour définir les accessoires, comme nous l'avons fait dans address.js .

Si nous créons des composants réutilisables pouvant être utilisés par d'autres développeurs de l'équipe, il est recommandé de définir des objets en tant qu'objets afin que toute personne utilisant le composant ait une idée claire de ce que devrait être le type de données et si c'est obligatoire ou facultatif.

Il est également appelé validation des accessoires . Le type peut être l'un des constructeurs natifs suivants:

  • Chaîne
  • Nombre
  • Booléen
  • Tableau
  • Objet
  • Fonction
  • ou un constructeur personnalisé

Quelques exemples de validation du prop depuis 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 cas de kebab

Les attributs HTML ne sont pas sensibles à la casse, ce qui signifie qu'ils ne peuvent pas différencier addresstype et addressType . Par conséquent, lorsque vous utilisez des noms de propriétés camelCase en tant qu'attributs, vous devez utiliser leurs équivalents kebab:
addressType doit être écrit en tant que address-type dans l'attribut HTML.

Accessoires dynamiques

Tout comme vous pouvez lier des données d'une vue au modèle, vous pouvez également lier des éléments à l'aide de la même directive v-bind pour transmettre des informations des composants parent à enfant.

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>

Résultat

hello world

Passer les accessoires lors de l'utilisation de Vue JSX

Nous avons un composant parent: Importer un composant enfant dans ce composant, nous passerons des accessoires via un attribut. Ici, l'attribut est "src" et nous passons aussi le "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} />   
        );
    }
};

Et un composant enfant, où il faut passer des accessoires. Nous devons spécifier les accessoires que nous passons.

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
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow