Use properties or slot for pass data to child element

Viewed 4957

I've a question about what it is the best way to pass some value from a father component to a child component and show the value, because I've tried to pass value with properties and slot and both ways work. Properties: I've a movement list and use repeat from lit-html (and method html to render) in the father component in order to create n child component giving the values in them properties.

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

Slot: I've a movement list and use repeat from lit-html (and method html to render) in the father component in order to create n child component giving the values in slot which were declared in the child component

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

Which it is the best way? When do I have to use one and the other?

3 Answers

Here is an example to pass of object's properties with using 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);

If you want pass any property, value or similar you must to use a Polymer property if the way is from parent to child (with a dispatch event if it is from child to parent).

The use of a <slot> is when you have created a space where other dev wants add more content. Polymer's guide says:

To allow children to render, you can add a element to your shadow tree. Think of the <slot> as a placeholder showing where child nodes will render.

So, if you want to pass a value from parent to child I would use a property.

You pass data as property and not the child element itself. This data will be something the child element needs to render perfectly.

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

You use slot when you dont know how the child element is being rendered. Say you're creating an element that other developers will use, you dont need to know how their elements is being structure or what data is needed. All you do is to create a slot as a placeholder so any developer can insert their template.

//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>`

Related