在通过 Svelte 每个块迭代对象时查找值
Posted
技术标签:
【中文标题】在通过 Svelte 每个块迭代对象时查找值【英文标题】:Looking up values while iterating through an object via a Svelte each block 【发布时间】:2021-08-04 20:54:12 【问题描述】:以下简化示例有效,但不确定它是否是最有效的方法,因为我在 Svelte 中的每个迭代块中多次调用 getLocation():
<script>
export let schedule =
locations: [
_id: 1,
name: 'Boston',
parking: 'Onstreet'
,
_id: 2,
name: 'New York',
parking: 'Paid lot'
],
sections: [
locationId: 2,
day: 1
,
locationId: 1,
day: 2
]
function getLocation(id)
return schedule.locations.find( ( _id ) => _id === id )
</script>
<template>
#each schedule.sections as section
<p>getLocation(section.locationId).name getLocation(section.locationId).parking</p>
/each
</template>
我可以使用的其他方法:
-
使用 locationId 作为键和 location 对象作为值填充 Map 对象,并在每个块中引用它。正在考虑它可能有更多的开销,因为我必须构建地图然后每次都通过键查找值。
在显示之前通过向部分对象添加位置属性来非规范化数据。当我传入数据时,不想对其进行变异或克隆的开销。
这个看起来很容易,但由于迭代可能效率较低...创建一个单元素数组,其中包含从 getLocation() 返回的位置对象,并使用内部每个块来访问这样的位置属性.. .
<template>
#each schedule.sections as section
#each [getLocation(section.locationId)] as location
<p>location.name location.parking</p>
/each
/each
</template>
我是 Svelte 的新手。对最有效的方法有什么想法吗?我的第一种方法是不是最好的(或者我离基地还很远)?
【问题讨论】:
【参考方案1】:我会说答案只取决于数据的情况。
我通常尽量避免使用任何函数作为模板的一部分(不包括操作)。这种默认做法来自使用 Vue2,其中计算的使用可以很容易地用于注入缓存数据,而不是在重新渲染时就地计算。不过,在 svelte 中,我发现反应性在确定组件中要更新的部分方面做得很好。
这是一个例子(复制粘贴到repl)
<script>
const list = ['uno', 'dos', 'tres', 'catorce'];
let somethingRandom = true
const splitWord = (word) =>
console.log(`split [$word]`)
return word.split('')
;
</script>
#each list as word
<div>
#each splitWord(word) as letter
<span>letter</span>
<input type="checkbox" bind:checked=somethingRandom> <!-- causes re-render-->
/each
</div>
<input bind:value=word> <!-- causes re-render -->
<input type="checkbox" bind:checked=somethingRandom><!-- does not cause to re-render -->
/each
只要您在内部循环 (#each splitWord(word) as letter
) 中有 <input type="checkbox" bind:checked=somethingRandom>
,就会重新渲染内部循环。
如果您将内部somethingRandom
输入注释掉并且只将它放在外部循环中,则更改somethingRandom
值不会导致内部循环重新呈现。
但是更改 <input bind:value=word>
会导致内部重新渲染
整个list
总是重新渲染
因此,如果您有一个庞大的数据集并且正在编辑 schedule.sections
和/或 schedule.locations
,那么您可能需要考虑添加某种形式的缓存。 Svelte 监视整个数组或对象的更改,因此如果您想实现可以根据单个项目更改进行缓存的东西,您可能需要手动实现很多缓存机制。
如果数据按时呈现,并且它没有改变,那么缓存或反规范化几乎没有好处(无论如何就性能而言)。
【讨论】:
以上是关于在通过 Svelte 每个块迭代对象时查找值的主要内容,如果未能解决你的问题,请参考以下文章
启用多重选择后如何从velve-select组件中获取所有值
for...of语句在可迭代对象(包括 Array,Map,Set,String,TypedArray,arguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语