我正在尝试获取一种材料设计风格的东西,其中位置名称会飞到标题中。似乎斯维尔特无法弄清这两个方面之间的联系。
演示:https://svelte.dev/repl/865750b1ffb642f59d317747bd9f3534?version=3.4.4
基本上,我尝试使其运行的方式是通过具有如下所示的地理位置列表:
{#each visibleLocations as location (location.id)}
<div
on:click={() => (selectedLocation = location)}
class="location"
animate:flip
out:send={{ key: location.id }}
in:receive={{ key: selectedLocation.id }}>
<div class="name"> {location.name} </div>
</div>
{/each}
然后我有一个看起来像这样的标题。注意,我必须将其包装在每个块中,以使编译器可以执行此操作。自然,这让我觉得自己做错了一些事情
{#each selectedLocaitonList as chosenLocaiton (chosenLocaiton.id)}
<div
class="header"
animate:flip
in:send={{ key: chosenLocaiton.id }}
out:receive={{ key: chosenLocaiton.id }}>
{#if chosenLocaiton.id}
<button on:click={() => (selectedLocation = { id: null })}>◀️</button>
{chosenLocaiton.name}
{:else}Pick a Location near you{/if}
</div>
{/each}
也许是不是因为selectedLocation是同一件事?我不确定如何解决这个问题,我希望通过ID。
答案 0 :(得分:2)
in
应始终与receive
配对,而out
应始终与send
配对; in:send
将始终给出奇怪的结果。您还发现这里的位置之间不匹配:
out:send={{ key: location.id }}
in:receive={{ key: selectedLocation.id }}
它们都必须相同。
animate
指令用于对列表中的项进行重新排序–因为在这种情况下,第一个列表始终从[x]
到[y]
,并且第二个总是从[]
到[x, y, z]
进行动画处理,没有共同的元素,因此使用该指令不是正确的地方。
使用crossfade
时,发送/接收的元素应具有相同的尺寸,并且理想情况下,彼此放置在一起时看起来应该可以(例如,相对于元素的边框在相同的位置键入内容,等等)。在这里,<button>
元素使事物的大小不同。
换句话说,有点像这样:https://svelte.dev/repl/f4386ec88df34e3b9a6b513e19374824?version=3.4.4
不幸的是,仍然存在一些视觉上的毛刺-因为我们使用比例转换作为后备,所以 layout 不会过渡,这意味着外边界会突然移入和移出放置而不是调整大小。我们可以改用slide
过渡,但是滑动元素和交叉淡入淡出元素似乎相互重叠。无论哪种情况,DOM中似乎都存在一个幻影元素,使布局变得混乱。我不确定这是否是Svelte错误(如果可以,是否可以修复),所以无需进一步调查,所以我提出了一个问题:https://github.com/sveltejs/svelte/issues/2957
答案 1 :(得分:1)
结果是,如果我交换out
和in
,那么它将按预期工作。不知道为什么会这样,所以需要一个更好的答案。