Home > other >  What is the best way to toggle between two different Lit components?
What is the best way to toggle between two different Lit components?

Time:11-03

I am working with Lit components. I want to create two buttons and toggle between two different components. What is the best approach to achieve that?

CodePudding user response:

The best way depends on your use case. In this case it is probably the simplest way.

  • Use a reactive property to maintain the state of which component to render. When a button is pressed, this state can change, and a reactive update is scheduled resulting in an efficient template update.
  • Have a parent that contains the two buttons and the state of which view to render, and then renders that view.

For more sophisticated component composition setups see lit.dev documentation on Component Composition. There is also a great video by the Lit core team on Event communication between components.

Here's a runnable example showing a small example of two buttons toggling between two different components:

<script type="module">
import {html, LitElement} from "https://cdn.jsdelivr.net/gh/lit/dist@2/core/lit-core.min.js"


class ContainerEl extends LitElement {
  static properties = {
    toggleComponent: {type: Boolean},
  };

  constructor() {
    super();
    this.toggleComponent = false;
  }

  render() {
    // Using a ternary to choose which template to use. Could also
    // do this with an `if` statement.
    const view = this.toggleComponent ?
        html`<view-b></view-b>` : html`<view-a></view-a>`;
    return html`
        <button @click=${() => {this.toggleComponent = false;}}>
          View A
        </button>
        <button @click=${() => {this.toggleComponent = true;}}>
          View B
        </button>
        ${view}
    `;
  }
}

class ViewA extends LitElement {
  render() { return html`<b>Element A</b>`; }
}

class ViewB extends LitElement {
  render() { return html`<i>Element B</i>`; }
}

customElements.define('container-el', ContainerEl);
customElements.define('view-a', ViewA);
customElements.define('view-b', ViewB);
</script>

<container-el></container-el>

In specific more complicated cases, the following directives could also be useful (but not in a simple situation such as this one):

  • cache directive: Caches rendered DOM when changing templates rather than discarding the DOM.
  • guard directive: Only re-evaluates the template when one of its dependencies changes.
  • Related