Как передать данные от дочернего элемента к родительскому с помощью двух компонентов Svelte в родительско-дочерних отношениях HTML

Я новичок в Svelte. У меня есть 2 компонента Svelte в отношениях родитель-потомок HTML - в отличие от отношений Svelte P / C (где один компонент Svelte импортирует другой).

В конце концов, мне нужно что-то вроде этого (может быть много приспособлений):

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

Я хотел бы, чтобы SvelteComponent определял заголовок, используемый в Accordion (он может быть динамическим). Я могу использовать для этого магазины, но это кажется слишком беспорядочным. Аккордеон действительно содержит слот, но я не вижу, как передавать информацию вверх. Кто-нибудь может предложить путь вперед?


person user49011    schedule 22.05.2020    source источник


Ответы (2)


Один из вариантов - использовать привязки компонентов. Это позволяет осуществлять двустороннюю привязку между значением в области компонента контейнера и опорой содержащегося в нем компонента.

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

и в SvelteComponent.svelte:

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

Каждый раз, когда SvelteComponent вносит изменения в defaultHeader, он будет распространяться обратно через привязку к файлу, который содержит Accordion и SvelteComponent, и применяет изменения обратно вниз. https://svelte.dev/tutorial/component-bindings

В качестве альтернативы вы можете предоставить функцию setHeader в качестве опоры для SvelteComponent, которая устанавливает значение заголовка:

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

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

Svelte отлично избавляет от шаблонов и лишнего лишнего кода. Я хочу зайти в этом настолько далеко, насколько могу.

Я считаю, что, используя ответ @skeletizzle, мне пришлось бы добавить переменную в контейнер Accordions для каждого Accordion и его дочернего элемента. ЭТО я хочу исключить (это загрязняет пространство имен контейнера для тривиальной операции). Поскольку Accordion и его дочерний элемент находятся в отношениях P / C - они знают друг о друге, и компилятор может установить прямую связь. Подумайте о подразумеваемом интерфейсе, в котором Accordion просматривает своего дочернего элемента и находит свойство с именем, скажем, «заголовок», автоматически, реактивно, использует его для своего собственного свойства заголовка.

Что я собираюсь сделать, так это использовать магазины, хотя, как было сказано, я считаю, что они слишком тяжелые, но не думаю, что у меня есть альтернатива.

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>

Еще есть переменная. но он пропущен в определении импорта

Одна вещь, которую это предотвращает, - это наличие более 1 экземпляра компонента.

person user49011    schedule 23.05.2020
comment
Спасибо за Ваш ответ. Это не привело к тому, что я искал - и я не думаю, что то, что мне нужно, существует. Как мой ответ; заявляет, что я просто пошел вперед и использовал магазины. - person user49011; 24.05.2020