0

也就是说,使用

array = array;

触发视图以当前刷新array

例如,以下使用

cards = [...cards, {name}];

向数组“添加”一个条目cards,但通过分配cards给一个新数组,并且cards在视图中将被刷新。

示例:https
://svelte.dev/repl/3ed20e7bac2e4b65944c98485d9217b3?version=3.18.1 (只需输入一些名称,下面的列表就会更新)。

但是,输入n名称时这是 O(n²),因为每次创建一个新数组都是 O(n)。如果 (1) 用户希望一次输入几个或十几个名字,这不是什么大问题,或者 (2) 用户可能输入一个名字几秒钟到 20 秒,那么任何延迟当条目多达 1000 个或 2000 个名称时,UI 的 0.2 秒不是一个大问题。(用户可能会更好地添加到服务器和数据库,以防万一停电。)

但如果我们不想要 O(n²) 时间,我们也可以使用:

    cards.push({name});
    cards = cards;

这将触发视图中的刷新。所以 Svelte 不做“脏检查”?与 Angular、Vue 和 React 相比,它们是通过实际将数组转换为字符串并检查数组是否发生变化来进行脏检查吗?

示例:https ://svelte.dev/repl/70cc3b08f6864ef387c691b8f126a7fd?version=3.18.1

如果没有该行cards = cards;,列表将不会在视图中更新:

示例:https ://svelte.dev/repl/25f41c51798d425e805fb4586a843363?version=3.18.1

cards = something;所以Svelte实际上并没有进行脏检查,而是cardscards = cards那么,如果我们使用它作为一种通用技术来标记某些东西是脏的,那么我们可以使用array.push()它来让程序运行得更快吗?Svelte 真的可以cards通过检测到有一个cards.push()语句来猜测这种情况发生了变化吗?

更新:发现通过为每个列表项添加一个键cards = cards是不需要的,我想知道为什么:

https://svelte.dev/repl/d78158ae54684bf28b8c2e9b527f1915?version=3.18.1

<ul>
  {#each cards as card, i (i)}
    <li>{card.name}</li>
  {/each}
</ul>
4

2 回答 2

4

将变量分配给自身是对编译器的提示,即需要更新视图的相关部分 -请参阅此处了解更多信息。它旨在允许您在需要性能的情况下使用可变对象和数组,但推动您使用不可变数据结构,因为这通常会导致更少的错误。

检测类似的东西array.push(...)并不实际——最好有一种单一、清晰的方式告诉编译器“这已经改变了”,而赋值运算符就是这样。

它使用键控的每个块而不是未键控的块的原因实际上是由于一个错误 - 我提出了一个问题:https ://github.com/sveltejs/svelte/issues/4373

于 2020-02-05T18:22:56.013 回答
2

您可以使用自定义存储来模拟“检测由push()方法引起的更改”。

请参阅 Rich Harris 的此 REPL https://svelte.dev/repl/2699eb0fe7dd4621b3e585aec1a30d01?version=3.17.3

于 2020-02-05T13:00:44.223 回答