You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

拖拽排序列表增删元素异常问题求助(Svelte+Tauri)

解决方案

核心问题

你遇到的问题是数组数据源同步失效:父组件+page.svelte中的sensors是唯一数据源,但拖拽排序后,SortableList.svelte内的数组变化没有同步回父组件。点击添加按钮时,代码基于父组件里未更新的原数组生成新数组,导致列表回到初始顺序。

修复步骤

1. 让SortableList同步排序结果到父组件

修改SortableList.svelte,利用svelte-dnd-action的finalize事件获取排序后的数组,通过自定义事件传递给父组件:

<script>
    import { sortable } from 'svelte-dnd-action';
    import { createEventDispatcher } from 'svelte';
    const dispatch = createEventDispatcher();
    
    export let list;

    function handleFinalize(event) {
        // 提取排序后的完整数组
        const sortedList = event.detail.items.map(item => item.data);
        // 发送事件通知父组件更新
        dispatch('update-list', sortedList);
    }
</script>

<div use:sortable={{ items: list }} on:finalize={handleFinalize}>
    {#each list as item (item.id)}
        <ListElement {item} />
    {/each}
</div>

2. 父组件接收更新并维护数据源

在+page.svelte中监听自定义事件,实时更新sensors数组:

<script>
    import SortableList from './SortableList.svelte';

    let sensors = [ 
        {id: 0, title: 'USB1'},
        {id: 1, title: 'USB2'},
        {id: 2, title: 'USB3'},
        {id: 3, title: 'File: abc.txt'},
        {id: 4, title: 'File: 123.txt'},        
    ];

    function buttonClick(){
        let i = sensors.length;
        sensors = [...sensors, {id:i, title:'great'}];
    }

    // 接收排序后的数组并更新数据源
    function updateSensors(event) {
        sensors = event.detail;
    }
</script>

<SortableList list={sensors} on:update-list={updateSensors} />
<button on:click={buttonClick}>添加元素</button>

3. 实现删除元素功能

在ListElement.svelte中添加删除按钮,触发自定义事件传递待删除元素的ID:

<script>
    import { createEventDispatcher } from 'svelte';
    const dispatch = createEventDispatcher();
    
    export let item;

    function handleDelete() {
        dispatch('delete-item', item.id);
    }
</script>

<div>
    <span>{item.title}</span>
    <button on:click={handleDelete}>删除</button>
</div>

在SortableList.svelte中转递删除事件:

{#each list as item (item.id)}
    <ListElement {item} on:delete-item={(e) => dispatch('delete-item', e.detail)} />
{/each}

最后在+page.svelte中处理删除逻辑:

<script>
    // ... 其他代码

    function deleteSensor(id) {
        sensors = sensors.filter(item => item.id !== id);
    }
</script>

<SortableList list={sensors} on:update-list={updateSensors} on:delete-item={deleteSensor} />

关键注意事项

  • 保持单一数据源:所有数组操作(排序、添加、删除)都在父组件中完成,子组件仅负责渲染和触发事件。
  • 不要直接修改子组件中的list prop:Svelte的props是单向绑定,直接修改无法同步回父组件,还会引发异常。
  • each循环必须添加(item.id)作为key:确保Svelte能正确跟踪元素位置,避免渲染混乱。

内容的提问来源于stack exchange,提问作者Georg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 10:20:10