Используйте свойства или слот для передачи данных в дочерний элемент

У меня вопрос о том, как лучше всего передать какое-то значение из родительского компонента в дочерний компонент и показать его, потому что я пытался передать значение с помощью свойств и слота, и оба способа работают. Свойства: у меня есть список движения и использовать repeat из лит-HTML (и метод html для рендеринга) в родительском компоненте, чтобы создать n дочерний компонент, дающий значения в их свойствах.

//father component
render(){
    return html`
        ${repeat(movements, movement => movement.id, (movement, index)=> html`
            <movement
            .id=${movement.id} .description=${movement.description} .amount=${movement.amount} .balance=${movement.balance}>
            </movement>
            <hr>
        `)}
    `    
}

//child component
render(){
    return html`
        <dt>${this.id}</dt>
        <dl>${this.description}</dl>
        <dl>${this.amount}</dl>
        <dl>${this.balance}</dl>
    `;
}

Слот: у меня есть список движения и использование repeat из лит-HTML (и метод html оказать) в родительском компоненте, чтобы создать n дочерний компонент, дающий значения в слоте, которые были объявлены в дочернем компоненте

//child component
render(){
    return html`
    <dd>
        <slot name="id"></slot>
        <slot name="description"></slot>
        <slot name="amount"></slot>
        <slot name="balance"></slot>
    </dd>
    `;
}

//father component
render(){
    return html`
        ${repeat(movements, movement=>movement.id, (movement, index)=>html`
            <movement>
                <dt slot="id"> ${movement.id} </dt>
                <dl slot="description"> ${movement.description} </dl>
                <dl slot="amount"> ${movement.amount} </dl>
                <dl slot="balance"> ${movement.balance} </dl>
            </movement>
        `)}
    `;
}

Какой это лучший способ? Когда я должен использовать один и другой?

4 ответа

Вот пример для передачи object's properties с использованием LitElement:

DEMO

import { LitElement, html } from '@polymer/lit-element'; 

class MyElement extends LitElement {

  static get properties() { return { 
    movements: {
        type:Object 
      }
    }
  }

  constructor(){
    super();
    // Initialize property here.
      this.movements = [{id:"123", amount:40000, description:"Bu yuzyilin en buyuk lideri Atatürk tür", balance:20000},{id:"123", amount:40000, description:"Tosun was here ! :) ", balance:20000},{id:"123", amount:40000, description:"Ne Mutlu Diyene, Buraarda ırkçı olmayahh :)) ", balance:20000}];
  }

 //father component
render(){
  return html`
         ${this.movements.map(movement => html`<movement-list  .id=${movement.id} .description=${movement.description} .amount=${movement.amount} .balance=${movement.balance}></movement-list>`)}

  `;
}
}

class MovementList extends LitElement {

  static get properties() { return { 
    id: {type:String},
    description: {type:String},
    amount: {type:Number},
    balance: {type:Number}
    }
  }
  //child component
render(){
    return html`
        <dt>${this.id}</dt>
        <dl>${this.description}</dl>
        <dl>${this.amount}</dl>
        <dl>${this.balance}</dl> 

    `;
}

}
customElements.define('my-element', MyElement);
customElements.define('movement-list', MovementList);

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

Использование <slot> это когда вы создали пространство, где другие разработчики хотят добавить больше контента. Руководство Полимера гласит:

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

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

Вы передаете данные как свойство, а не как дочерний элемент. Эти данные будут чем-то, что дочерний элемент должен правильно отображать.

// Parent
 render(){
   return html`${this.list.map(data => html`<child-element .data${data}></child-element>`)}`
}

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

//custom-element
render(){
   return html`<div> <slot></slot></div>`
}

// user 
render(){
return html`<custom-element>
          <my-element></my-element>
          <p>I am a paragraph in a slot</p>
          <div>You can see me too</div>
     </custom-element>`

Это еще один способ передать собственность.

Если вы используете слоты в родительском компоненте, хотите передать свойство родительского компонента дочернему компоненту (пожалуйста, посмотрите index.html).

например: если вы хотите ввести свойство в компоненте Item, но не можете передать его в слоты.

вот способ:

      var cType = this.parentNode.getAttribute('type');

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

      // index.html - where user use the components.

<body>
  <main>
   <ajs-container type="uniform">
    <ajs-item size="2"></ajs-item>
    <ajs-item size="3"></ajs-item>
    <ajs-item size="2"></ajs-item>
   </ajs-container>
  </main>
</body>

// parent-component

render() {
   return html`
     <div class="container">
         <slot></slot>
     </div>`;
}
customElements.define('ajs-container', Container);


// child-component

render() {
   const ItemData = html`<slot></slot>`;
   return html`
     <style>
        :host {
          ${this.hostStyle.join(';')}
        }
     </style>
     <div class="item">
         ${ItemData}
     </div>`;
}

get hostStyle() {
  const st = [];
  var cType = this.parentNode.getAttribute('type'); // by using this you can extract parent property.
  if(cType == "uniform") {
    st.push(`color: green`);
  }else {
    st.push(`color: red`);
  }
  return st;
}

customElements.define('ajs-item', Item);
Другие вопросы по тегам