Zoeken…


Opmerkingen

camelCase <=> kebab-koffer

Onthoud bij het definiëren van de namen van uw props dat HTML-kenmerknamen niet hoofdlettergevoelig zijn. Dat betekent dat als je een prop definieert in kamelengeval in je componentdefinitie ...

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

... je moet het in je HTML-component als my-prop noemen.

Gegevens doorgeven van ouder op kind met rekwisieten

In Vue.js heeft elke componentinstantie een eigen geïsoleerde scope , wat betekent dat als een bovenliggende component een onderliggende component heeft, de onderliggende component een eigen geïsoleerde scope heeft en de bovenliggende component een eigen geïsoleerde scope heeft.

Voor elke middelgrote tot grote app voorkomt het volgen van best practices conventies veel hoofdpijn tijdens de ontwikkelingsfase en daarna tijdens het onderhoud. Een van de dingen die u moet volgen, is dat u niet rechtstreeks vanuit de onderliggende component naar oudergegevens verwijst / muteert . Dus hoe verwijzen we dan naar de oudergegevens vanuit een onderliggende component?

Welke oudergegevens vereist zijn in een onderliggend onderdeel, moet aan het kind worden doorgegeven als props van de ouder.

Use Case: Stel we hebben een gebruiker de database met twee tabellen users en addresses met de volgende velden:
users tabel

naam telefoon e-mail
John Mclane (1) 234 5678 9012 [email protected]
James Bond (44) 777 0007 0077 [email protected]

addresses tabel

blok straat stad
Nakatomi-torens Broadway New York
Mi6 huis Buckingham Road Londen

en we willen drie componenten hebben om overeenkomstige gebruikersinformatie overal in onze app weer te geven

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:''
        }
    },
}  

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

We tonen de phone en email mailgegevens, die eigenschappen van user-component in contact-details die geen telefoon- of e-mailgegevens hebben.

Gegevens doorgeven als rekwisieten

Dus binnen de user-component.js in de sjablooneigenschap , waar we de component <contact-details> , geven we de telefoon en de e- mailgegevens van <user-component> (hoofdcomponent) door aan <contact-details> ( onderliggende component) door het dynamisch te binden aan de rekwisieten - :phone="phone" en :email="email die hetzelfde is als v-bind:phone="phone" en v-bind:email="email"

Props - Dynamische binding

Aangezien we de rekwisieten dynamisch binden, wordt elke wijziging in telefoon of e-mail binnen de bovenliggende component, dwz <user-component> , onmiddellijk weerspiegeld in de onderliggende component, bijvoorbeeld <contact-details> .

Props - als letterlijk

Als we de waarden van telefoon en e-mail echter zouden hebben doorgegeven als letterlijke tekenreekswaarden zoals phone="(44) 777 0007 0077" email="[email protected]" dan zou dit geen gegevenswijzigingen weergeven die in de bovenliggende pagina plaatsvinden component.

Eenrichtingsbinding

Standaard is de richting van de veranderingen van boven naar beneden, dwz elke wijziging in dynamisch gebonden rekwisieten in de bovenliggende component wordt doorgegeven aan de onderliggende component, maar elke wijziging in de propwaarden in een onderliggende component wordt niet doorgegeven aan de bovenliggende component.

Voor bijvoorbeeld: als vanuit de <contact-details> we de e-mail van te veranderen [email protected] tot [email protected] , de ouder data dwz telefoongegevens woning in <user-component> zal bevatten nog steeds een waarde van de [email protected] .

Echter, als we de waarde van de e-mail te veranderen van [email protected] tot [email protected] in de bovenliggende component ( <user-component> in onze use case), dan de waarde van e-mail in het kind component ( <contact-details> in ons gebruik) wordt automatisch gewijzigd in [email protected] - de wijziging van de ouder wordt onmiddellijk doorgegeven aan het kind.

Tweerichtingsbinding

Als we tweerichtingsbinding willen, moeten we expliciet tweerichtingsbinding specificeren als :email.sync="email" plaats van :email="email" . Als we nu de waarde van prop in de onderliggende component wijzigen, wordt de wijziging ook weerspiegeld in de bovenliggende component.

In een middelgrote tot grote app is het zeer moeilijk om de ouderstatus van de onderliggende status te detecteren en bij te houden, vooral tijdens het debuggen - Wees voorzichtig .

Er is geen .sync-optie beschikbaar in Vue.js 2.0. De tweerichtingsbinding voor rekwisieten wordt afgeschaft in Vue.js 2.0 .

Eenmalige binding

Het is ook mogelijk om expliciete eenmalige binding te definiëren als :email.once="email , het is min of meer vergelijkbaar met het doorgeven van een letterlijke waarde, omdat latere wijzigingen in de waarde van de bovenliggende eigenschap niet worden doorgegeven aan het kind.

CAVEAT
Wanneer Object of Array als prop wordt doorgegeven, worden ze ALTIJD DOORGEGEVEN DOOR REFERENTIE , wat betekent ongeacht het bindende type dat expliciet is gedefinieerd :email.sync="email" of :email="email" of :email.once="email" , Als e-mail een object of een array in het bovenliggende item is, heeft elke wijziging van de waarde in de onderliggende component, ongeacht het bindingstype, ook invloed op de waarde in het bovenliggende element.

Props als Array

In het bestand contact-details.js hebben we props:['phone', 'email'] als een array gedefinieerd, wat prima is als we geen fijnkorrelige controle met props willen.

Rekwisieten als object

Als we fijnere controle over rekwisieten willen, zoals

  • als we willen definiëren welk type waarden acceptabel zijn als de prop
  • wat een standaardwaarde voor de prop zou moeten zijn
  • of een waarde MOET (vereist) moet worden doorgegeven voor de prop of is deze optioneel

dan moeten we objectnotatie gebruiken voor het definiëren van de rekwisieten, zoals we hebben gedaan in address.js .

Als we herbruikbare componenten schrijven die ook door andere ontwikkelaars in het team kunnen worden gebruikt, is het een goede gewoonte om rekwisieten als objecten te definiëren, zodat iedereen die de component gebruikt een duidelijk idee heeft van wat het soort gegevens moet zijn en of het is verplicht of optioneel.

Het wordt ook wel props-validatie genoemd . Het type kan een van de volgende native constructors zijn:

  • Draad
  • Aantal
  • Boolean
  • reeks
  • Voorwerp
  • Functie
  • of een aangepaste constructor

Enkele voorbeelden van propvalidatie zoals overgenomen uit 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

HTML-attributen zijn niet hoofdlettergevoelig, wat betekent dat het geen onderscheid kan maken tussen addresstype en addressType , dus als we camelCase-propnamen als attributen gebruiken, moeten we hun kebab-case (door koppeltekens gescheiden) equivalenten gebruiken:
addressType moet worden geschreven als address-type in HTML-kenmerk.

Dynamische rekwisieten

Net zoals u gegevens uit een weergave aan het model kunt binden, kunt u ook rekwisieten binden met dezelfde v-bind-richtlijn voor het doorgeven van informatie van bovenliggende naar onderliggende componenten.

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>

Resultaat

hello world

Props doorgeven tijdens het gebruik van Vue JSX

We hebben een oudercomponent: als we een onderliggende component importeren, geven we rekwisieten door via een kenmerk. Hier is het kenmerk 'src' en we passeren ook de '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} />   
        );
    }
};

En een kindercomponent, waar we rekwisieten moeten doorgeven. We moeten specificeren welke rekwisieten we passeren.

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
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow