Javascript 如何在虚拟列表中保持苗条组件的状态?
我正在用Svelte开发一个甘特图组件,它由100个行组件组成,每个行组件包含多个任务组件。可以拖动和移动任务。性能是一个优先事项,我使用虚拟列表只渲染可见的行Javascript 如何在虚拟列表中保持苗条组件的状态?,javascript,svelte,virtualscroll,Javascript,Svelte,Virtualscroll,我正在用Svelte开发一个甘特图组件,它由100个行组件组成,每个行组件包含多个任务组件。可以拖动和移动任务。性能是一个优先事项,我使用虚拟列表只渲染可见的行 <div class="scrollable"> {#each visibleRows as row (row.id)} <div class="row"> {#each row.tasks as task (task.id)} &l
<div class="scrollable">
{#each visibleRows as row (row.id)}
<div class="row">
{#each row.tasks as task (task.id)}
<Task from={task.from} to={to}/>
{/each}
</div>
{/each}
</div>
模板引用了task.propname中的每个道具,我不确定这是否是最简单的方式,因为不清楚到底设置了什么
我可以像这样绑定任务变量
const {task} = this.get();
task.from = new Date();
this.set({task});
<Task bind:from=task.from
bind:to={task.to}/>
为了提高性能,我应该选择哪种方法?或者有更好的方法来处理这个问题?您应该更改数据数组,而不是改变对象。通过改变数组中的对象,Svelte不知道数组已更改 通过使用Svelte v3并使用存储而不是普通阵列,可以对阵列进行如下更改:
// data.js
...
import { writable } from 'svelte/store';
export default writable(getData())
...
// App.svelte
<script>
...
import items from './data.js';
function updateContent(item) {
const index = $items.indexOf(item)
$items = [
...$items.slice(0, index),
{ ...item, content: 'updated content' },
...$items.slice(index + 1)
]
}
...
</script>
<VirtualList items={$items} let:item bind:start bind:end>
...
<button on:click={() => updateContent(item)}>update content</button>
...
</VirtualList>
//data.js
...
从'svelte/store'导入{writable};
导出默认可写(getData())
...
//App.svelte
...
从“/data.js”导入项目;
函数更新内容(项){
常量索引=$items.indexOf(item)
$items=[
…$items.slice(0,索引),
{…项,内容:'更新内容'},
…$items.slice(索引+1)
]
}
...
...
updateContent(项目)}>更新内容
...
完整示例:
您可以在此处阅读有关更新数组和对象的更多信息:似乎您没有选择使用onstate事件。您在使用onstate事件时遇到了什么问题?对此有任何更新吗?我将继续使用第一种方法,但将
任务
属性重命名为_task、_data或_state,以进一步将其区分为某种“受保护状态”属性。使用onstate
的最后一种方法会在每次状态更改时触发,即使是那些不应该更新task
,并且很容易在其中包含不必要的数据…在您的示例中,items
在data.js
中实例化,不是吗?你为什么在updateContent
中调用$items
,而不是items
?
<Task {task}
{...task}/>
onstate({ changed, current, previous }) {
const {task} = this.get();
Object.assign(task, current);
this.set({task});
},
// data.js
...
import { writable } from 'svelte/store';
export default writable(getData())
...
// App.svelte
<script>
...
import items from './data.js';
function updateContent(item) {
const index = $items.indexOf(item)
$items = [
...$items.slice(0, index),
{ ...item, content: 'updated content' },
...$items.slice(index + 1)
]
}
...
</script>
<VirtualList items={$items} let:item bind:start bind:end>
...
<button on:click={() => updateContent(item)}>update content</button>
...
</VirtualList>