悬停在对象条目上触发不必要的Svelte反应



我有一个对象,我用每个块循环。当我悬停时,我临时改变了实际对象条目上的一个属性,并用它来分配一个类。这可以正常工作,但它也经常导致不必要的触发其他反应。

<script>
let things = [
{ id: 1, name: 'apple' },
{ id: 2, name: 'banana' },
{ id: 3, name: 'carrot' },
{ id: 4, name: 'doughnut' },
{ id: 5, name: 'egg' },
];

function makePretty(somethings) {
const prettyThings = somethings.map(thing => thing.name).join(' ');
console.log(prettyThings);
return prettyThings;
}

$: prettyThings = makePretty(things)
</script>
<ul>
{#each things as thing (thing.id)}
<li 
class:hover={thing.hover}
on:mouseenter={() => (thing.hover = true)}
on:mouseleave={() => (thing.hover = false)}
>
{thing.name}
</li>
{/each}
</ul>
<style>
.hover {
background-color: cyan;
}
</style>

REPL: https://svelte.dev/repl/c658cccd0bc2471a8f9c4758387340c5?version=3.48.0在控制台中,您可以看到当您用鼠标移动列表时触发prettyThings上的反应性的频率。

我确实意识到这是预期的行为,因为"事物"对象在每次鼠标进入和鼠标离开时都有效地改变了。因此,每次都调用prettyThings。

在不改变对象本身的情况下,将悬停应用于对象数组中的"行",这是一种理想的方式吗?在这样做时,对象应该仍然可以被其他操作(例如添加,删除,…)实时修改。

一种方法是将渲染拆分为一个单独的组件。

<script>
export let thing;
</script>
<li class:hover={thing.hover}
on:mouseenter={() => (thing.hover = true)}
on:mouseleave={() => (thing.hover = false)} >
{thing.name}
</li>
<style>
.hover {
background-color: cyan;
}
</style>
{#each things as thing (thing.id)}
<ItemDisplay {thing} />
{/each}

REPL

也许有更好的方法。

编辑:您可以存储' ' Row Hovered"在一个单独的变量中,然后基于"HoveredRowId === thing.id">

应用样式
<script>
let things = [
{ id: 1, name: 'apple' },
{ id: 2, name: 'banana' },
{ id: 3, name: 'carrot' },
{ id: 4, name: 'doughnut' },
{ id: 5, name: 'egg' },
];

let hoveredId = 0;

function makePretty(somethings) {
const prettyThings = somethings.map(thing => thing.name).join(' ');
console.log(prettyThings);
return prettyThings;
}

$: prettyThings = makePretty(things)
</script>
<ul>
{#each things as thing (thing.id)}
<li 
class:hover={thing.id === hoveredId}
on:mouseenter={() => (hoveredId = thing.id)}
on:mouseleave={() => (hoveredId = 0)}
>
{thing.name}
</li>
{/each}
</ul>
<p>
Hovered ID: {hoveredId}
</p>
<style>
.hover {
background-color: cyan;
}
</style>

REPL: https://svelte.dev/repl/e157abc957874228983c9eafb2246aa3?version=3.48.0

最新更新