简体   繁体   English

从 Svelte 中的父组件跟踪子组件组件中的 state(Svelte 中从子组件到父组件的数据流/通信)

[英]Keep track of state in child-component component from withing parent component in Svelte (Data-flow/communication from child to parent in Svelte)

As I am quite new to the way of reactive thinking I am having a hard time to grasp some basics concepts.由于我对反应式思维方式还很陌生,因此我很难掌握一些基本概念。 I also think to this question there are many ways to solve this which is quite overwhelming for a begginer.我也认为对于这个问题,有很多方法可以解决这个问题,这对于初学者来说是相当艰巨的。 So here is my simple question:所以这是我的简单问题:

I have a parent component and a child component.我有一个父组件和一个子组件。 The only thing (for now) that the parent component is doing is importing the child component and rendering it.父组件(目前)唯一要做的就是导入子组件并渲染它。 The child component itself goes (on click) through an array of text and displays it.子组件本身(在单击时)通过一组文本并显示它。 When reached the end I want to unmount this component.当到达终点时,我想卸载这个组件。 However, as far as I know, this is usually done from the parent.但是,据我所知,这通常是由父母完成的。 Eg by wrapping it in a pseudo if-statement like this:例如,通过将其包装在一个伪 if 语句中,如下所示:

{#if childNotFinished}
    <Child/>
{/if}

But I simply do not know what the best way is to communicate to the parent that the child is "done"但我根本不知道最好的方式是与父母沟通孩子“完成”

My two components look like this and are in the repl here ( https://svelte.dev/repl/c787b13ebe524af8af3d97d71e7c8510?version=3.49.0 ):我的两个组件看起来像这样,并且在此处的 repl 中( https://svelte.dev/repl/c787b13ebe524af8af3d97d71e7c8510?version=3.49.0 ):

# App.svelte
<script>
import Intro from "./Intro.svelte"
</script>

<Intro></Intro>
<!--
{#if IntroFinished}
Do something new, import a new component, ....
{/if}
-->
# Intro.svelte
<script>
  let currentStep = 0;
  
  let steps = [
    { text: "this" },
    { text: "is" },
    { text: "a" },
    { text: "test" },
  ];

  function showNext() {
    if (currentStep === steps.length - 1) {
      return;
    }
    currentStep++;
  }

  function showPrev() {
    if (currentStep === 0) {
      return;
    }
    currentStep--;
  }
</script>

<button on:click={showPrev}>Last</button>
<button on:click={showNext}>Next</button>

<div>
  {steps[currentStep].text}
</div>

{#if currentStep === steps.length - 1}
  <button>Start New Thing</button>
{/if}

Maybe there are some best practices or good ressources on how to approach something like this.也许有一些关于如何处理这样的事情的最佳实践或良好的资源。 Or more general on data-flow (up and down) in svelte.或者更一般的关于 svelte 中的数据流(向上和向下)。 It feels like there are coming so many new possibilities each time that I do not know which to use and how to solve this.感觉每次都有很多新的可能性出现,我不知道该使用哪个以及如何解决这个问题。

In this case I would either use a bound property or an event.在这种情况下,我将使用绑定属性或事件。

With the property approach you declare a property on the child:使用属性方法,您可以在孩子上声明一个属性:

export let finished = false;
{#if currentStep === steps.length - 1}
  <button on:click={() => finished = true}>Start New Thing</button>
{/if}

Which then can be read via bind: in the parent:然后可以通过bind:在父级中读取:

<script>
    import Intro from "./Intro.svelte";
    let finished = false;
</script>

{#if finished == false}
    <Intro bind:finished ></Intro>
{:else}
  Something else
{/if}

Via events you create a dispatcher and dispatch an event from the child component:通过事件,您可以 创建一个调度程序并从子组件调度一个事件:

import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
{#if currentStep === steps.length - 1}
  <button on:click={() => dispatch('finished')}>Start New Thing</button>
{/if}

Which then is handled in the parent:然后在父级中处理:

<script>
    import Intro from "./Intro.svelte";
    let finished = false;
</script>

{#if finished == false}
    <Intro on:finished={() => finished = true} ></Intro>
{:else}
  Something else
{/if}

An event is probably a bit cleaner, because the component is not supposed to revert its state, so there is no real need for it to be a property.一个事件可能更干净一些,因为该组件不应该恢复它的 state,所以它没有真正需要成为一个属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM