So it looks like Svelte is not truly deleting the TextItem but moving the content from the next item into its place.
(因此,看起来Svelte并没有真正删除TextItem,而是将内容从下一个项目移到了它的位置。)
Yes, absolutely, this is what is happening.
(是的,绝对是这样。)
Svelte (like React) only recreate an element in a given position when its nature has obviously changed, for example if the tag name is not the same.
(Svelte(像React一样)仅在其性质明显改变(例如,标记名称不同)时才在给定位置重新创建元素。)
Otherwise, it is considered that it is the same element / component with just some props / state that has changed.(否则,可以认为它是相同的元素/组件,只是某些道具/状态发生了变化。)
In order to hint the framework that the identity of an element has changed, you must the key
functionality.
(为了提示框架元素的身份已更改,您必须具有key
功能。)
In React, it's a literal key
prop.(在React中,它是字面意义上的key
道具。)
In Svelte, keys are only supported in {#each ...}
blocks ( for now? ).(在Svelte中,键仅在{#each ...}
块中受支持( 现在是吗? )。)
The syntax is the following ( docs ):(语法如下( docs ):)
{#each expression as name, index (key)}...{/each}
# also works, I think it is an oversight in the docs currently
{#each expression as name, (key)}...{/each}
The value of the key
must be unique to each item for it to work.
(key
的值对于每个项目都必须唯一,才能起作用。)
Typically you'd use an id of sort.(通常,您会使用排序ID。)
But truly, it can be anything.(但实际上,它可以是任何东西。)
If the value change for the element / component at a given position, then it will be recreated.(如果元素/组件在给定位置的值更改,则将重新创建它。)
So, in your case, you could fix your issue by using the item type as a key, for example:
(因此,根据您的情况,可以通过使用项目类型作为键来解决问题,例如:)
{#each $listStore as item, i (item.type)}
<Wrapper item={item} store={listStore} myIndex={i} />
{/each}
This fixes the issue you're asking about, but it's not such a great idea I must say.
(这可以解决您要询问的问题,但是我必须说这不是一个好主意。)
For other reasons, you'd better add real unique ids to your items and use them instead.(出于其他原因,您最好将真实的唯一ID添加到商品中,而改用它们。)
With the above code, items of the same type will continue to share DOM elements, and that's probably not what you want.(使用上面的代码,相同类型的项目将继续共享DOM元素,而这可能并不是您想要的。)
You may have issues with focus or internal state (value) of DOM elements like inputs, for example.(例如,您可能对DOM元素(如输入)的焦点或内部状态(值)有疑问。)
So, something like this is better and is probably the way to go:
(因此,类似这样的方法更好,并且可能是解决方法:)
<script>
import {writable} from "svelte/store";
import Wrapper from "./Wrapper.svelte";
const items = [
{
id: 1,
type: "text",
value: "Test 1"
},
{
id: 2,
type: "img",
value: "https://media.giphy.com/media/KzW9EkUE6NJrwqG0UX/giphy.gif"
}
];
const listStore = writable(items);
</script>
{#each $listStore as item, i (item.id)}
<Wrapper item={item} store={listStore} myIndex={i} />
{/each}