Sök…


Anmärkningar

camelCase <=> kebab-fodral

När du definierar namnen på dina props alltid komma ihåg att HTML-attributnamn är okänsliga för versaler. Det betyder att om du definierar en prop i kamelfall i din komponentdefinition ...

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

... du måste kalla det i din HTML-komponent som min-prop.

Vidarebefordra data från förälder till barn med rekvisita

I Vue.js har varje komponentinstans sitt eget isolerade omfång , vilket innebär att om en överordnad komponent har en underordnad komponent - har barnkomponenten sitt eget isolerade omfång och överordnade komponenten har sitt eget isolerade omfång.

För alla apper med medelstor till stor storlek förhindrar det att följa konventioner om bästa praxis massor av huvudvärk under utvecklingsfasen och sedan efter underhåll. En av sådana saker att följa är att undvika att hänvisa till / mutera förälderdata direkt från barnkomponenten . Så hur hänvisar vi till förälderdata från en barnkomponent?

Oavsett förälderdata som krävs i en barnkomponent bör överföras till barnet som props från föräldern.

Använd fall : Anta att vi har en users med två tabeller users och addresses med följande fält:
users tabell

namn telefon e-post
John Mclane (1) 234 5678 9012 [email protected]
James Bond (44) 777 0007 0077 [email protected]

addresses tabell

blockera gata stad
Nakatomi Towers Broadway New York
Mi6 House Buckingham Road London

och vi vill ha tre komponenter för att visa motsvarande användarinformation var som helst i vår app

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

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

Vi visar phone och email postdata, som är egenskaperna för user-component i contact-details som inte har telefon- eller e-postdata.

Vidarebefordra data som rekvisita

Så inom user-component.js i mallegenskapen , där vi inkluderar <contact-details> -komponenten, överför vi telefonen och e- postdata från <user-component> (moderkomponent) till <contact-details> ( underordnad komponent) genom att dynamiskt binda den till rekvisita - :phone="phone" och :email="email som är samma som v-bind:phone="phone" och v-bind:email="email"

Rekvisita - dynamisk bindning

Eftersom vi dynamiskt binder rekvisita kommer alla förändringar i telefon eller e-post inom moderkomponenten, dvs <user-component> omedelbart återspeglas i underordnade komponenter, dvs <contact-details> .

Rekvisita - som bokstäver

Men om vi skulle ha gått värdena på telefon och e-post som sträng bokstavliga värden som phone="(44) 777 0007 0077" email="[email protected]" skulle det inte återspegla några dataförändringar som inträffar i överordnade komponent.

Envägsbindande

Som standard är ändringarnas riktning från topp till botten, dvs varje ändring av dynamiskt bundna rekvisita i överkomponenten kommer att spridas till underkomponenten men alla ändringar i prop-värdena i en underordnad komponent sprids inte till överordnade.

Till exempel: om vi från <contact-details> ändrar e-postmeddelandet från [email protected] till [email protected] , kommer överordnad data, dvs. telefondataegenskap i <user-component> , fortfarande att innehålla ett värde av [email protected] .

Men om vi ändrar värdet på e-post från [email protected] till [email protected] i [email protected] ( <user-component> i vårt användningsfall) kommer värdet på e-post i underkomponenten ( <contact-details> i vårt användningsfall) kommer automatiskt att ändras till [email protected] - förändring av förälder sprids omedelbart till barnet.

Tvåvägsbindning

Om vi vill ha tvåvägsbindning måste vi uttryckligen ange :email.sync="email" som :email.sync="email" istället för :email="email" . Om vi nu ändrar värdet på prop i barnkomponenten kommer reflektionen att återspeglas också i moderkomponenten.

I en medelstor till stor app kommer det att vara mycket svårt att upptäcka förälderstatus från barntillståndet och hålla reda på särskilt när du felsöker - Var försiktig .

Det finns inget .sync-alternativ tillgängligt i Vue.js 2.0. Tvåvägsbindningen för rekvisita avskrivs i Vue.js 2.0 .

Engångsbindning

Det är också möjligt att definiera explicit engångs bindande :email.once="email , det är mer eller mindre liknar passera en bokstavlig, eftersom eventuella förändringar i den överordnade fastighetsvärde inte fortplanta sig till barnet.

VARNING
När objekt eller array skickas som rekvisit, passas de ALLTID PÅ REFERENS , vilket betyder oberoende av vilken bindningstyp som är exakt definierad :email.sync="email" eller :email="email" eller :email.once="email" , om e-post är ett objekt eller en matris i föräldern, oavsett bindningstyp, kommer alla förändringar i prop-värdet inom barnkomponenten också att påverka värdet i föräldern.

Rekvisita som Array

I filen contact-details.js vi definierat props:['phone', 'email'] som en matris, vilket är bra om vi inte vill ha finkornig kontroll med rekvisita.

Rekvisita som objekt

Om vi vill ha mer finkornig kontroll över rekvisita, som

  • om vi vill definiera vilken typ av värden som är acceptabla som rekvisit
  • vad som ska vara ett standardvärde för rekvisiten
  • huruvida ett värde MÅSTE (krävs) som ska skickas för rekvisiten eller är det valfritt

då måste vi använda objektnotation för att definiera rekvisita, som vi gjort i address.js .

Om vi författar återanvändbara komponenter som kan användas av andra utvecklare i teamet också, är det en bra praxis att definiera rekvisita som objekt så att alla som använder komponenten har en klar uppfattning om vad som ska vara typen av data och om det är obligatoriskt eller valfritt.

Det kallas också rekvisitionsvalidering . Typen kan vara vilken som helst av följande inbyggda konstruktörer:

  • Sträng
  • siffra
  • Boolean
  • Array
  • Objekt
  • Fungera
  • eller en anpassad konstruktör

Några exempel på validering av prop som tagits från 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-fodral

HTML-attribut är addresstype addressType , vilket innebär att de inte kan skilja mellan addresstype och addressType , så när vi använder camelCase prop-namn som attribut måste vi använda deras kebab-case (bindestreck) ekvivalenter:
addressType ska skrivas som address-type i HTML-attribut.

Dynamiska rekvisita

Precis som du kan binda data från en vy till modellen kan du också binda rekvisita med samma v-bindningsdirektiv för att överföra information från föräldrar till barnkomponenter.

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>

Resultat

hello world

Skickar rekvisita när du använder Vue JSX

Vi har en överordnad komponent: Importerar en underordnad komponent i den skickar vi rekvisita via ett attribut. Här är attributet 'src' och vi passerar 'src' också.

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} />   
        );
    }
};

Och en barnkomponent, där vi måste skicka rekvisita. Vi måste specificera vilka rekvisita som vi passerar.

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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow