Поиск…


замечания

camelCase <=> кебаб-чехол

При определении имен ваших props всегда помните, что имена атрибутов HTML не зависят от регистра. Это означает, что если вы определяете prop в случае верблюда в определении вашего компонента ...

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

... вы должны назвать это в своем HTML-компоненте как my-prop.

Передача данных от родителя к ребенку с помощью реквизита

В Vue.js каждый экземпляр компонента имеет свою изолированную область видимости , что означает, что если родительский компонент имеет дочерний компонент, дочерний компонент имеет свою изолированную область, а родительский компонент имеет свою изолированную область.

Для любого приложения от среднего до большого размера в соответствии с рекомендациями по наилучшей практике предотвращается много головных болей на этапе разработки, а затем после технического обслуживания. Одна из таких вещей заключается в том, чтобы избежать ссылок на / исходные данные родительских данных непосредственно из дочернего компонента . Итак, как мы ссылаемся на родительские данные из дочернего компонента?

Независимо от того, какие родительские данные необходимы в дочернем компоненте, он должен быть передан ребенку в качестве props родителя.

Пример использования . Предположим, у нас есть пользовательская база данных с двумя users и addresses таблиц со следующими полями:
таблица users

название Телефон Эл. адрес
Джон Мклане (1) 234 5678 9012 [email protected]
Джеймс Бонд (44) 777 0007 0077 [email protected]

addresses таблица

блок улица город
Башни Накатоми Бродвей Нью-Йорк
Mi6 House Buckingham Road Лондон

и мы хотим иметь три компонента для отображения соответствующей пользовательской информации в любом месте нашего приложения

пользовательский 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:''
        }
    },
}  

контакт-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>

Мы показываем данные phone и email , которые являются свойствами user-component в contact-details которые не содержат телефонных или электронных данных.

Передача данных в виде реквизита

Таким образом, внутри user-component.js в свойстве шаблона , где мы включаем компонент <contact-details> , мы передаем телефон и данные электронной почты из <user-component> (родительский компонент) в <contact-details> ( дочерний компонент), динамически привязывая его к реквизитам - :phone="phone" и :email="email который аналогичен v-bind:phone="phone" и v-bind:email="email"

Опоры - Динамическое связывание

Поскольку мы динамически связываем реквизиты с любыми изменениями в телефоне или электронной почте внутри родительского компонента, то есть <user-component> будет немедленно отражен в дочернем компоненте, т.е. <contact-details> .

Реквизит - как литералы

Однако, если бы мы передали значения телефона и электронной почты в виде строковых литералов, таких как phone="(44) 777 0007 0077" email="[email protected]" то это не отразило бы какие-либо изменения данных, которые происходят в родительском составная часть.

Односторонняя привязка

По умолчанию направление изменений сверху вниз, т.е. любое изменение динамически привязанных реквизитов в родительском компоненте будет распространяться на дочерний компонент, но любое изменение значений prop в дочернем компоненте не будет распространяться на родителя.

Например, если из <contact-details> мы меняем электронное письмо с [email protected] на [email protected] , родительские данные, т. [email protected] [email protected] данных телефона в <user-component> все равно будут содержать значение [email protected] .

Однако, если мы изменим значение электронной почты от [email protected] на [email protected] в родительском компоненте ( <user-component> в нашем случае использования), то значение электронной почты в дочернем компоненте ( <contact-details> в нашем случае использования) автоматически изменится на [email protected] - изменение родительского [email protected] мгновенно распространяется на ребенка.

Двусторонняя привязка

Если мы хотим двустороннюю привязку, мы должны явно указать двустороннюю привязку как :email.sync="email" вместо :email="email" . Теперь, если мы изменим значение prop в дочернем компоненте, изменение будет отражено и в родительском компоненте.

В средстве и крупном приложении изменение состояния родителя из дочернего состояния будет очень сложно обнаружить и отслеживать особенно во время отладки - будьте осторожны .

В Vue.js 2.0 не будет никакой опции .sync. Двусторонняя привязка для реквизита устарела в Vue.js 2.0 .

Одноразовая привязка

Также можно определить явное одноразовое привязку как :email.once="email , оно более или менее похоже на передачу литерала, потому что любые последующие изменения в значении родительского свойства не будут распространяться на ребенка.

ПРЕДОСТЕРЕЖЕНИЕ
Когда Object или Array передаются как prop, они ВСЕГДА ПРОХОДА ПО ССЫЛКЕ , что означает независимо от типа привязки, явно определенного :email.sync="email" или :email="email" или :email.once="email" , если адрес электронной почты является объектом или массивом в родительском объекте, то независимо от типа привязки любое изменение значения prop в дочернем компоненте также влияет на значение в родительском.

Реквизит в виде массива

В файле contact-details.js мы определили props:['phone', 'email'] в качестве массива, что прекрасно, если мы не хотим, чтобы мелкозернистый элемент управления с реквизитами.

Реквизит как объект

Если мы хотим более мелкозернистого контроля над реквизитами, например

  • если мы хотим определить, какие типы значений приемлемы в качестве опоры
  • что должно быть значением по умолчанию для опоры
  • является ли значение ДОЛЖНЫ (требуется) для передачи пропеллера или оно необязательно

то нам нужно использовать объектную нотацию для определения реквизита, как это было сделано в address.js .

Если мы создаем повторно используемые компоненты, которые могут быть использованы другими разработчиками в команде, то хорошей практикой является определение реквизита в качестве объектов, чтобы кто-либо, использующий компонент, имел четкое представление о том, каким должен быть тип данных, и он является обязательным или необязательным.

Он также называется проверкой реквизита . Тип может быть любым из следующих встроенных конструкторов:

  • строка
  • Число
  • логический
  • массив
  • объект
  • функция
  • или пользовательский конструктор

Некоторые примеры проверки профайла, взятые из 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 против кебаба

HTML-атрибуты нечувствительны к регистру, что означает, что он не может различать addresstype и addressType , поэтому при использовании имен propel camelCase в качестве атрибутов нам необходимо использовать их эквиваленты кебаба (дефисграничные):
addressType должен быть записан как address-type в атрибуте HTML.

Динамические реквизиты

Так же, как вы можете привязывать данные к представлению к модели, вы также можете связывать реквизиты с помощью той же директивы v-bind для передачи информации от родительского к дочерним компонентам.

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>

Результат

hello world

Передача реквизитов при использовании Vue JSX

У нас есть родительский компонент: импортируя в него дочерний компонент, мы передадим реквизит через атрибут. Здесь атрибут «src», и мы также передаем «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} />   
        );
    }
};

И дочерний компонент, где нам нужно пройти реквизит. Нам нужно указать, какие реквизиты мы проходим.

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
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow