jfi*_*fix 3 javascript svelte svelte-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": {
...
}
}
Run Code Online (Sandbox Code Playgroud)
我通过异步获取onMount在主组件中检索数据,这效果很好。App.svelte然后我想将每个对象传递给其相应的组件,因此该stats对象被传递给Stats.svelte,该heatmap对象传递给Heatmap.svelte等等。
为了说明我的问题,Stats.svelte我尝试显示每个时间段的百分比值,例如:
此外,每个 CSS 类将基于一些阈值来更改颜色(x >= 95:绿色,95 > x >= 90:黄色,x < 90:红色)。
因此,需要一些基本计算,我想在通用函数中使用这些计算,如下所示。
该stats对象确实是从父组件传入的App.svelte,如果我想做的只是通过{#await}块在 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>
Run Code Online (Sandbox Code Playgroud)
有多种方法可以做到这一点,但一种方法是将calcPercentage作为stats参数,然后反应性地调用它。
export let stats
let currentYearClass, currentYearStat
const calcPercentage = (stats, period) => {
currentYearStat = stats[persion}......
currentYearClass = 'green'
}
$: stats && calcPercentage(stats, 'currentYear')
Run Code Online (Sandbox Code Playgroud)
编辑:一些解释
原始解决方案的第一个问题,您可能注意到的是,组件在没有正确数据的情况下安装,导致统计信息未定义。
上述解决方案分两步进行:
$: stats && calcPercentage(stats, 'currentYear')
Run Code Online (Sandbox Code Playgroud)
第一部分定义了一个响应式语句,它将检查stats 的计算结果是否为 true,除非未定义、为 false 或 0,否则它将执行某些操作。如果stats为 true,它将执行该函数。
第二部分是与之前相同的函数,我在此处添加了stats参数,尽管在这种情况下严格不需要它,因为函数会这样做,因为之前每次统计数据更改时都会执行并且是一个类似 true 的值。
有了这两个,当挂载反应式语句时,由于stats未定义,该函数将失败,该函数不会执行。一旦数据进入,它将被重新评估,统计数据不再是未定义的并且函数将被触发。
额外的
当反应式语句采用以下形式时:
$: myfunction(myvar)
Run Code Online (Sandbox Code Playgroud)
它将针对myvar 的每次值更改执行,即使在安装期间也是如此(考虑它从不存在变为未定义?)。这意味着您必须将检查移至函数本身,对于某些情况,这可能是需要的,例如,这实际上是赋值的一部分,而函数本身是在组件外部定义的
import heavyCalc from 'heavy/calc/function`
$: value = heavyCalc(otherValue)
Run Code Online (Sandbox Code Playgroud)