Skip to content

Dynamic components #640

@Rich-Harris

Description

@Rich-Harris

This idea isn't at all fleshed out, but it's something that's come up a few times. Occasionally it's useful to create nested components dynamically:

<!-- this... -->
<[CurrentRoute]/>

<!-- ...instead of this: -->
{{#if route === 'home'}}
  <Home/>
{{elseif route === 'about'}}
  <About/>
{{elseif ...}}
  <-- ... -->
{{/if}}

The same idea could be used for e.g. lazy-loading components:

<LazyLoad src='./SomeComponent.html'>
  <p>loading, please wait...</p>
</LazyLoad>
<!-- LazyLoad.html -->
{{#if Component}}
  <[Component]/>
{{else}}
  {{yield}}
{{/if}}

<script>
  export default {
    oncreate () {
      import(this.get('src')).then(Component => {
        this.set({ Component });
      });
    }
  };
</script>

(To be clear, you could create the lazy loaded component programmatically, but this way is clearer and doesn't rely on you making a container element.)

What I haven't figure out is how you'd pass props down in that second case if you don't know know what props there are. Does it require a special syntax like <[Component] ...props/>? How do we know when props have changed, and ensure that changes are batched?

Also, <[Component]/> breaks syntax colouring, at least in GitHub and VSCode. Bit annoying. Any suggestions for an alternative that doesn't? This seems to work, though it looks a bit wild frankly:

<dynamic(foo ? Bar : Baz) ...props/>

(As an aside, <:Self/> and <:Window/> syntax colouring is broken in recent versions of VSCode... grrr.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions