How to pass data from child to parent with 2 Svelte components in HTML parent-child relationship

﹥>﹥吖頭↗ 提交于 2021-02-10 04:29:30

问题


I'm new to Svelte. I have 2 Svelte components in an HTML parent-child relationship – as opposed to a Svelte P/C relationship (where 1 Svelte component imports another).

Ultimately, I want something like this (could have many Accs.):

  <Accordion header={--property from SvelteComponent-- }>
    <SvelteComponent />
  </Accordion>

I would like the SvelteComponent to define the header used in the Accordion (it can be dynamic). I can use stores for this but that seems too messy. Accordion does contain a slot but I can’t see how to pass information upward. Can anyone suggest a path forward?


回答1:


One option is to use component bindings. This allows a two-way binding between a value in the scope of a container component and a prop of the contained component.

<Accordion {header}>
    <SvelteComponent bind:header={header} />
</Accordion>

and in SvelteComponent.svelte:

<script>
    export let header = "defaultHeader";
</script>

Whenever SvelteComponent makes a change to defaultHeader, it will propogate back up via the binding to the file which contains the Accordion and SvelteComponent, and apply the changes back downward. https://svelte.dev/tutorial/component-bindings

Alternatively, you can provide a setHeader function as a prop to SvelteComponent, which sets the value of header:

//SvelteComponent.svelte
<script>
    export let setHeader;
</script>

<div on:click={() => setHeader("myHeader")}>
    My Svelte Component
</div>



回答2:


Svelte is great at getting rid of boilerplate and unnecessary extra code. I want to take that as far as I can.

I believe using @skeletizzle answer that I would have to add a variable to the container of the Accordions, for each Accordion and its child. THAT is what I want to eliminate (it pollutes the namespace of the container for a trivial operation). Since the Accordion and its child are in a P/C relation - they know about each other and the compiler could make communication direct. Think of an implied interface where the Accordion looks in its child and it it finds a prop named, say 'header', automatically, reactively, uses that for its own header prop.

What I am going to do is use stores though as stated, I feel they are too heavy - but don't think I have an alternative.

WrappedComponent.svelte

<script context="module">
  import { writable } from 'svelte/store'
  export let thisComponentHeader = writable('default header')
</script>

App.svelte

import WrappedComponent, { thisComponentHeader } from './WrappedComponent.svelte'
...
<Accord header={$thisComponentHeader}>
  <WrappedComponent />
</Accord>

There still is a variable. but it is socked away in the import definition

One thing this prevents is having more than 1 instance of the component.



来源:https://stackoverflow.com/questions/61960147/how-to-pass-data-from-child-to-parent-with-2-svelte-components-in-html-parent-ch

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!