Szukaj…


Uwagi

camelCase <=> kebab-case

Podczas definiowania nazw props zawsze pamiętaj, że w nazwach atrybutów HTML rozróżniana jest wielkość liter. Oznacza to, że jeśli zdefiniujesz prop w przypadku wielbłąda w definicji komponentu ...

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

... musisz to nazwać w komponencie HTML jako my-prop.

Przekazywanie danych od rodzica do dziecka za pomocą rekwizytów

W Vue.js każda instancja komponentu ma swój własny izolowany zakres , co oznacza, że jeśli komponent nadrzędny ma komponent podrzędny - komponent podrzędny ma swój izolowany zakres, a komponent nadrzędny ma swój izolowany zakres.

W przypadku aplikacji o średnich i dużych rozmiarach przestrzeganie konwencji najlepszych praktyk zapobiega wielu problemom głowy podczas fazy projektowania, a następnie po konserwacji. Jedną z takich rzeczy do naśladowania jest unikanie odwoływania się / mutowania danych nadrzędnych bezpośrednio z komponentu potomnego . Więc w jaki sposób odwołujemy się do danych nadrzędnych z komponentu podrzędnego?

Wszelkie dane rodzica wymagane w elemencie potomnym należy przekazać dziecku jako props od rodzica.

Przypadek użycia : Załóżmy, że mamy bazę danych użytkowników z dwoma tabelami users i addresses z następującymi polami:
Tabela users

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

Tabela addresses

blok ulica Miasto
Nakatomi Towers Broadway Nowy Jork
Mi6 House Buckingham Road Londyn

i chcemy mieć trzy elementy do wyświetlania odpowiednich informacji o użytkownikach w dowolnym miejscu w naszej aplikacji

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

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

Wyświetlamy dane phone i email - email , które są właściwościami elementu user-component w danych contact-details które nie zawierają danych telefonu ani wiadomości e-mail.

Przekazywanie danych jako rekwizyty

Tak więc w pliku user-component.js we właściwości szablonu , gdzie uwzględniamy komponent <contact-details> , przekazujemy telefon i dane e-mail z <user-component> (komponent nadrzędny) do <contact-details> ( komponent potomny) poprzez dynamiczne wiązanie go z rekwizytami - :phone="phone" i :email="email który jest taki sam jak v-bind:phone="phone" i v-bind:email="email"

Rekwizyty - dynamiczne wiązanie

Ponieważ dynamicznie wiążemy rekwizyty, każda zmiana w telefonie lub e-mailu w komponencie nadrzędnym, tj. <user-component> zostanie natychmiast odzwierciedlona w komponencie podrzędnym, tj. <contact-details> .

Rekwizyty - jako literały

Jeśli jednak przekazalibyśmy wartości telefonu i wiadomości e - mail jako wartości literału ciągu, takie jak phone="(44) 777 0007 0077" email="[email protected]" to nie odzwierciedlałoby to żadnych zmian danych, które nastąpiłyby w rodzicu składnik.

Wiązanie w jedną stronę

Domyślnie kierunek zmian jest od góry do dołu, tj. Każda zmiana dynamicznie związanych rekwizytów w komponencie nadrzędnym zostanie propagowana do komponentu potomnego, ale każda zmiana wartości rekwizytów w komponencie potomnym nie zostanie propagowana do rodzica.

Na przykład: jeśli w <contact-details> zmienimy wiadomość e-mail z [email protected] na [email protected] , dane nadrzędne, tj. Właściwość danych telefonu w <user-component> nadal będą zawierać wartość [email protected] .

Jeśli jednak zmienimy wartość wiadomości e-mail z [email protected] na [email protected] w elemencie nadrzędnym ( <user-component> komponent <user-component> w naszym przypadku użycia), wówczas wartość e-maila w elemencie podrzędnym ( <contact-details> w naszym przypadku użycia) zmieni się automatycznie na [email protected] - zmiana rodzica jest natychmiast przenoszona na dziecko.

Wiązanie dwukierunkowe

Jeśli chcemy powiązania dwukierunkowego, musimy jawnie określić powiązanie dwukierunkowe jako :email.sync="email" zamiast :email="email" . Teraz, jeśli zmienimy wartość prop w komponencie potomnym, zmiana zostanie odzwierciedlona również w komponencie macierzystym.

W średnich i dużych aplikacjach zmiana stanu nadrzędnego ze stanu podrzędnego będzie bardzo trudna do wykrycia i śledzenia, szczególnie podczas debugowania - bądź ostrożny .

W Vue.js 2.0 nie będzie dostępna żadna opcja .sync. Dwukierunkowe wiązanie rekwizytów jest przestarzałe w Vue.js 2.0 .

Wiązanie jednorazowe

Możliwe jest również zdefiniowanie jednoznacznego jednorazowego wiązania jako :email.once="email , jest ono mniej więcej podobne do przekazywania literału, ponieważ wszelkie późniejsze zmiany wartości właściwości nadrzędnej nie zostaną przeniesione do potomka.

CAVEAT
Gdy Obiekt lub Tablica są przekazywane jako rekwizyt, są ZAWSZE PRZEKAZANE PRZEZ ODNIESIENIE , co oznacza bez względu na jawnie zdefiniowany typ powiązania :email.sync="email" lub :email="email" lub :email.once="email" , jeśli wiadomość e-mail jest obiektem lub tablicą w obiekcie nadrzędnym, to niezależnie od typu powiązania, każda zmiana wartości prop w komponencie podrzędnym wpłynie również na wartość w obiekcie nadrzędnym.

Rekwizyty jako szyk

W pliku contact-details.js zdefiniowaliśmy props:['phone', 'email'] jako tablicę, co jest w porządku, jeśli nie chcemy precyzyjnej kontroli rekwizytów.

Rekwizyty jako obiekt

Jeśli chcemy bardziej precyzyjnej kontroli nad rekwizytami, na przykład

  • jeśli chcemy zdefiniować, jakie wartości są dopuszczalne jako rekwizyt
  • jaka powinna być domyślna wartość dla prop
  • czy wartość musi być przekazana dla rekwizytu MUSI (wymagana), czy jest opcjonalna

następnie musimy użyć notacji obiektowej do zdefiniowania rekwizytów, tak jak zrobiliśmy to w address.js .

Jeśli tworzymy komponenty wielokrotnego użytku, które mogą być również używane przez innych programistów w zespole, dobrą praktyką jest definiowanie rekwizytów jako obiektów, aby każdy, kto korzysta z komponentu, miał jasne pojęcie o tym, jaki powinien być typ danych i czy jest obowiązkowe lub opcjonalne.

Jest również nazywany sprawdzaniem poprawności rekwizytów . Typem może być dowolny z następujących rodzimych konstruktorów:

  • Strunowy
  • Numer
  • Boolean
  • Szyk
  • Obiekt
  • Funkcjonować
  • lub niestandardowy konstruktor

Niektóre przykłady sprawdzania poprawności wniosku zaczerpnięte z 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

W atrybutach HTML rozróżniana jest addresstype liter, co oznacza, że nie można rozróżnić między addresstype a addressType , dlatego podczas używania nazw addressType camelCase jako atrybutów musimy używać ich odpowiedników w kebabie (rozdzielanych łącznikami):
addressType powinien być zapisany jako address-type w atrybucie HTML.

Dynamiczne rekwizyty

Tak jak jesteś w stanie powiązać dane z widoku do modelu, możesz również powiązać rekwizyty przy użyciu tej samej dyrektywy v-bind do przekazywania informacji z komponentów nadrzędnych do komponentów podrzędnych.

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>

Wynik

hello world

Przekazywanie rekwizytów podczas korzystania z Vue JSX

Mamy komponent nadrzędny: importując komponent podrzędny, przekażemy rekwizyty za pomocą atrybutu. Tutaj atrybut to „src”, a my przekazujemy również „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} />   
        );
    }
};

I element potomny, w którym musimy przekazywać rekwizyty. Musimy określić, które rekwizyty mijamy.

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
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow