$derived
派生状态通过 $derived
符文声明:
<script>
let count = $state(0);
let doubled = $derived(count * 2);
</script>
<button onclick={() => count++}>
{doubled}
</button>
<p>{count} 的两倍是 {doubled}</p>
$derived(...)
内的表达式应该没有副作用。Svelte 将不允许在派生表达式内进行状态更改(例如 count++
)。
与 $state
一样,你可以将类字段标记为 $derived
。
Svelte 组件中的代码仅在创建时执行一次。如果没有
$derived
符文,即使count
发生变化,doubled
也会保持其原始值。
$derived.by
有时你需要创建不适合放在简短表达式中的复杂派生。在这些情况下,你可以使用 $derived.by
,它接受一个函数作为参数。
<script>
let numbers = $state([1, 2, 3]);
let total = $derived.by(() => {
let total = 0;
for (const n of numbers) {
total += n;
}
return total;
});
</script>
<button onclick={() => numbers.push(numbers.length + 1)}>
{numbers.join(' + ')} = {total}
</button>
本质上,$derived(expression)
等同于 $derived.by(() => expression)
。
理解依赖关系
在 $derived
表达式(或 $derived.by
函数体)内同步读取的任何内容都被视为派生状态的依赖项。当状态发生变化时,派生将被标记为脏数据(dirty),并在下次读取时重新计算。
要使一段状态不被视为依赖项,请使用 untrack
。