Search code examples
javascriptdata-bindingsvelte

Svelte bind is not working when customElement: true is set


I want to build a custom element using Svelte.

Thus in rollup.config.js I set customElement: true, and then I have to use the to refer to my child components.

But I found that in this way, the bind will not work. Here is the code example

HelloWorld.svelte (child)

<script>
    import Hello from './components/Hello'
    import World from './components/World'
    export let value;
</script>

<svelte:options tag={'x-app-helloworld'}/>
<input type="text" bind:value={value} >

<input>
<x-app-hello />
<x-app-world />

App.svslte(parent) part of it.

<x-app-helloworld bind:value={value}/>

Then the parent will show an error: 'value' is not a valid binding on <x-app-helloworld> elements.

How could I solve this bind problem?


Solution

  • Bindings work on regular elements because Svelte knows which event corresponds to each binding — for example, it knows that the value of an <input> changes when the element fires a change or input event.

    With custom elements, there's no way to know what event (if any) the parent should be listening for. And there isn't currently a neat way to dispatch events from inside the element. So the best option is to pass in a callback to the custom element, and call it whenever the value changes:

    <x-app-helloworld onValueChange="{(x) => value = x}"/>
    
    <script>
      export let onValueChange;
      export let value;
    
      $: onValueChange(value);
    </script>