4

I am learning LWC and I understood the concept of Slots & Public Properties.

But I am not clear regarding when, in which conditions should we use Slots, Public Properties (@api) and Getter properties?

Can someone please help me understand?

10

The broad difference is that with @api attribute, is the public reactive property of the component, which can be passed through the parent. Note that this is like the backend(data) property of the component.

Pass data from the owner component.

Also, with getters and setters, you can call the child component method from parent component or get some value from the child component.

Whether

Slots are the places holders in the component, where parent component can pass HTML elements, components (Aura not supported here), slots are the UI property which is overwritten from a parent.

Pass markup from the owner component.

So let's understand concepts closely.


@api

To expose a public property, decorate it with @api. Public properties define the API for a component. An owner component that uses the component in its markup can access the component’s public properties. Public properties are reactive. If the value of a reactive property changes, the component rerenders. When a component rerenders, all the expressions used in the template are reevaluated.

How to define an @api property.

// todoItem.js
import { LightningElement, api } from 'lwc';
export default class TodoItem extends LightningElement {
    @api itemName = 'New Item';
}

<!-- todoItem.html -->
<template>
    <div class="view">
        <label>{itemName}</label>
    </div>
</template>

How to access if from the parent component.

<!-- todoApp.html -->
<template>
    <div class="listing">
        <c-todo-item item-name="Milk"></c-todo-item>
        <c-todo-item item-name="Bread"></c-todo-item>
    </div>
</template>

A component that declares a public property can set only its default value. A parent component that uses the component in its markup can set the component’s public property value. In our example, the c-todo-item component can’t update the value of the itemName property in the todoItem.js file.

How to user getters and setters, @api methods.

With get, set you can perform some operation in the child component whenever the public attribute is changed from the parent.

With @api enabled method You can call the method of child component from the parent (This concept is very similar to aura:method in aura components).

To execute logic each time a public property is set, write a custom setter. If you write a setter for public property, you must also write a getter. Annotate either the getter or the setter with @api, but not both. It’s a best practice to annotate the getter.

To hold the property value inside the getter and setter, use a private property. If you want the component to rerender when the private property’s value changes, @track it.

How to define get/set.

// todoItem.js
import { LightningElement, api, track } from 'lwc';
export default class TodoItem extends LightningElement {
    @track
    uppercaseItemName;

    @api
    get itemName() {
        return this.uppercaseItemName;
    }

    set itemName(value) {
       this.uppercaseItemName = value.toUpperCase();
    }

}

You can set these values from a parent like a public attribute in the kebab case.

How to define @api method:

// childLwc.js
import { LightningElement, api } from 'lwc';

export default class ChildLwc extends LightningElement {
    @api
    callFromParent() {
        console.log('in callFromParent()');
        // do some stuff.
    }
}

How to call @api method:

// methodCaller.js
import { LightningElement } from 'lwc';

export default class MethodCaller extends LightningElement {
    video = "https://www.w3schools.com/tags/movie.mp4";

    doSomethingOnChild() {
        this.template.querySelector('c-child-lwc').callFromParent();
    }
}

Slot

Add a slot to a component’s HTML file so a parent component can pass markup into the component. A component can have zero or more slots. A slot (<slot></slot>) is a placeholder for markup that a parent component passes into a component’s body. Slots are part of the Web Component specification.

There are two types of slots

  1. Unnamed slot.
  2. Named slot.

How to define slots.

<!-- namedSlots.html -->
<template>
    <p>First Name: <slot name="firstName">Default first name</slot></p> <!-- named slot -->
    <p>Last Name: <slot name="lastName">Default last name</slot></p> <!-- named slot -->
    <p>Description: <slot>Default description</slot></p> <!-- unnamed slot -->
</template>

How to pass named slots from the parent component.

<!-- slotsWrapper.html -->
<template>
    <c-named-slots>
        <span slot="firstName">Willy</span>
        <span slot="lastName">Wonka</span>
        <span>Chocolatier</span>
    </c-named-slots>
</template>

The c-slots-wrapper component passes: Willy into the firstName slot Wonka into the lastName slot Chocolatier into the unnamed slot Here’s the rendered output.


Finally

  • So when you want to pass data from parent use @api.

  • When you want to pass markup from parent use slots.

  • When you want to do something every time public attribute is changed then use getter/setters.

  • When you want to call a method from child component use @api method.

Know everything about @api here.

Know more about getters/setters/child component methods here.

Know everything about slots here.

Happy coding!

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy