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": {
...
}
}
我通过 App.svelte
主组件中的 onMount
通过异步获取检索数据,效果很好。然后我想将每个对象传递给其相应的组件,因此 stats
对象传递给 Stats.svelte
,heatmap
对象传递给 Heatmap.svelte
等
为了说明我的问题,在 Stats.svelte
中,我试图显示每个时间段的百分比值,例如:
- 当年:100%
- 过去三十天:93%
- 过去 100 天:92%
- 所有时间:92%
另外,CSS class for each 会根据一些阈值来改变颜色(x >= 95: green, 95 > x >= 90: yellow, x < 90: 红色).
所以需要一些基本的计算,我想在通用函数中使用这些计算,如下所示。
stats
对象确实从父组件 App.svelte
传入,如果我只想通过 [=21] 在 HTML 中显示它的值=] 块,这会工作正常。但是,我想做一些计算,所以我想调用一个函数来使用 stats
对象的数据,但我不知道如何在合适的时候调用这个函数。在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>
有几种方法可以做到这一点,但一种方法是让 calcPercentage
接受 stats
作为参数,然后响应式地调用它。
export let stats
let currentYearClass, currentYearStat
const calcPercentage = (stats, period) => {
currentYearStat = stats[persion}......
currentYearClass = 'green'
}
$: stats && calcPercentage(stats, 'currentYear')
编辑:一些解释
原始解决方案的第一个问题,您可能注意到的是组件 mounted 没有正确的数据,使得 stats未定义。
上述解决方案分两步进行:
$: stats && calcPercentage(stats, 'currentYear')
这第一部分定义了一个响应式语句,它将检查 stats 是否为真,除非它未定义、为假或 0,否则它将执行某些操作。如果 stats 为真它将执行函数。
第二部分是一个与之前相同的函数,我在这里添加了 stats 参数,尽管在这种情况下 严格不需要 ,因为函数会执行,因为每次 stats 更改时都会执行,并且是一个类似真实的值。
有了这两个,当挂载反应语句时会失败,因为 stats 是未定义的,函数不会被执行。一旦数据进来,它会被重新评估,stats不再是undefined并且函数触发。
额外
当反应语句的形式为:
$: myfunction(myvar)
它会为 myvar 的每个值 变化执行,即使在安装期间也是如此(考虑它从不存在到未定义?)。这意味着您必须将检查移至函数本身,在某些情况下可能需要这样做,例如,这实际上是赋值的一部分,而函数本身是在组件外部定义的
import heavyCalc from 'heavy/calc/function`
$: value = heavyCalc(otherValue)
我正在学习 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": {
...
}
}
我通过 App.svelte
主组件中的 onMount
通过异步获取检索数据,效果很好。然后我想将每个对象传递给其相应的组件,因此 stats
对象传递给 Stats.svelte
,heatmap
对象传递给 Heatmap.svelte
等
为了说明我的问题,在 Stats.svelte
中,我试图显示每个时间段的百分比值,例如:
- 当年:100%
- 过去三十天:93%
- 过去 100 天:92%
- 所有时间:92%
另外,CSS class for each 会根据一些阈值来改变颜色(x >= 95: green, 95 > x >= 90: yellow, x < 90: 红色).
所以需要一些基本的计算,我想在通用函数中使用这些计算,如下所示。
stats
对象确实从父组件 App.svelte
传入,如果我只想通过 [=21] 在 HTML 中显示它的值=] 块,这会工作正常。但是,我想做一些计算,所以我想调用一个函数来使用 stats
对象的数据,但我不知道如何在合适的时候调用这个函数。在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>
有几种方法可以做到这一点,但一种方法是让 calcPercentage
接受 stats
作为参数,然后响应式地调用它。
export let stats
let currentYearClass, currentYearStat
const calcPercentage = (stats, period) => {
currentYearStat = stats[persion}......
currentYearClass = 'green'
}
$: stats && calcPercentage(stats, 'currentYear')
编辑:一些解释
原始解决方案的第一个问题,您可能注意到的是组件 mounted 没有正确的数据,使得 stats未定义。
上述解决方案分两步进行:
$: stats && calcPercentage(stats, 'currentYear')
这第一部分定义了一个响应式语句,它将检查 stats 是否为真,除非它未定义、为假或 0,否则它将执行某些操作。如果 stats 为真它将执行函数。
第二部分是一个与之前相同的函数,我在这里添加了 stats 参数,尽管在这种情况下 严格不需要 ,因为函数会执行,因为每次 stats 更改时都会执行,并且是一个类似真实的值。
有了这两个,当挂载反应语句时会失败,因为 stats 是未定义的,函数不会被执行。一旦数据进来,它会被重新评估,stats不再是undefined并且函数触发。
额外
当反应语句的形式为:
$: myfunction(myvar)
它会为 myvar 的每个值 变化执行,即使在安装期间也是如此(考虑它从不存在到未定义?)。这意味着您必须将检查移至函数本身,在某些情况下可能需要这样做,例如,这实际上是赋值的一部分,而函数本身是在组件外部定义的
import heavyCalc from 'heavy/calc/function`
$: value = heavyCalc(otherValue)