繁体   English   中英

Svelte - 如何等待从父组件传入的数据?

[英]Svelte - how to wait for data that is being passed in from parent component?

我正在学习 Svelte,我想在三个组件中使用来自一个 JSON API 的数据。 数据如下所示:

{
  "stats": {
    "currentYear": {
      "total": 6,
      "success": 6
    },
    "thirty": {
      "total": 30,
      "success": 28
    },
    "hundred": {
      "total": 100,
      "success": 92
    },
    "allTime": {
      "total": 789,
      "success": 728
    }
  },
  "heatmap": {
     ...
  },
  "other": {
     ...
  }
}

我通过异步获取通过onMount主组件中的App.svelte检索数据,这很好用。 然后我想将每个 object 传递给其对应的组件,因此stats object 传递给Stats.svelteheatmap object 传递给Heatmap.svelte等。

为了说明我的问题,在Stats.svelte我试图显示每个时间段的百分比值,例如:

  • 本年度:100%
  • 过去三十天:93%
  • 过去 100 天:92%
  • 所有时间:92%

此外,每个 CSS class 将基于一些阈值来更改颜色(x >= 95:绿色,95 > x >= 90:黄色,x < 90:红色)。

所以需要一些基本的计算,我想在通用 function 中进行,如下所示。

stats object 确实是从父组件App.svelte的,如果我只想通过{#await}块在 HTML 中显示它的值,这将正常工作。 但是,我想做一些计算,所以我想调用一个 function 来使用stats对象的数据,但我不知道如何在适当的时候调用这个 function。 onMount上调用是不行的,因为太早了,还没有收到从父组件进来的数据。

<script>
    import { onMount } from "svelte"
    
    export let stats

    let currentYearClass, currentYearStat

    const calcPercentage = async (period) => {
        currentYearStat = stats[period].currentYearSuccess * 100 / stats[period].currentYearTotal
        currentYearClass = 'green'
    }

    onMount( async () => {
        calcPercentage('currentYear')
    })
</script>
<div id="stats">
{#await stats}
    <div>Waiting for stats ...</div>
{:then stats}
    <div class="{currentYearClass}" id="currentYear">{currentYearStat}</div>
    ...
    ...
{/await}
</div>

有几种方法可以做到这一点,但一种方法是让calcPercentagestats作为参数,然后反应性地调用它。

export let stats
let currentYearClass, currentYearStat

const calcPercentage = (stats, period) => {
   currentYearStat = stats[persion}......
   currentYearClass = 'green'
}

$: stats && calcPercentage(stats, 'currentYear')

编辑:一些解释

原始解决方案的第一个问题,您可能注意到的一点是,在没有正确数据的情况下安装了组件,导致未定义统计信息

上述解决方案分两步进行:

$: stats && calcPercentage(stats, 'currentYear')

第一部分定义了一个反应性语句,它将检查stats的计算结果是否为 true,除非它未定义、false 或 0,否则它将执行某些操作。如果stats为 true,它将执行 function。

第二部分与之前的 function 相同,我在此处添加了stats参数,尽管在这种情况下严格不需要它,因为 function 将,因为之前执行每次stats更改并且是一个类似于 true 的值。

有了这两个,当挂载反应性语句时,由于stats未定义,function 不会执行。 一旦数据进入,它将被重新评估, stats不再是未定义的,并且 function 会触发。

额外的

当反应性语句采用以下形式时:

$: myfunction(myvar)

它会在 myvar 的每个值更改时执行,即使在挂载期间也是如此(考虑它从不存在变为未定义?)。 这意味着您必须将检查移至 function 本身,对于某些情况,这可能是需要的,例如,这实际上是分配的一部分,而 function 本身是在组件外部定义的

import heavyCalc from 'heavy/calc/function`

$: value = heavyCalc(otherValue)

暂无
暂无

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

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