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

Sortablejs(Svelte)如何为动态列表初始化时设置ID?

解决svelte-sortable动态列表初始化无法设置索引ID的问题

问题背景

使用Sortablejs结合svelte-sortable实现拖拽重排时,动态列表初始化阶段无法为元素设置基于索引的ID。目前仅能通过onChange函数在列表更新后设置编号ID,但onstart、onload等Sortable钩子均无法生效,希望实现类似Svelte #each循环自动生成索引ID的效果。

当前代码:

<script>
    import Sortable from "svelte-sortable";

    // 长度未知的Svelte Store数组
    import { items } from "../store/links";

   // Sortable配置项
    const options = {
        animation: 150,
        dataIdAttr: "data-id",
        onChange: function (evt) {
            [].forEach.call(
                evt.from.getElementsByClassName("sortable_item"),
                function (el, index) {
                    el.setAttribute("id", index);
                }
            );
        },
    };
</script>


<Sortable items={$items} let:item {options}>
    <div class="sortable_item">
        {item.item}
    </div>
</Sortable>

补充:Svelte原生#each生成索引ID的方式:

{#each items as item, index}
<div id={index.toString()}>{item}</div>
{/each}

解决方案

方案一:直接利用svelte-sortable的slot索引(推荐)

svelte-sortable的组件插槽支持直接获取当前项的index参数,和#each的用法完全一致,不需要手动操作DOM或依赖Sortable钩子。

修改后的代码:

<script>
    import Sortable from "svelte-sortable";
    import { items } from "../store/links";

    const options = {
        animation: 150,
        dataIdAttr: "data-id"
        // 无需再通过onChange设置ID
    };
</script>

<Sortable items={$items} let:item let:index {options}>
    <div class="sortable_item" id={index.toString()}>
        {item.item}
    </div>
</Sortable>

方案二:用Svelte的onMount钩子初始化ID

如果因版本限制无法使用slot索引,可借助Svelte的onMount生命周期钩子,在组件渲染完成后为元素批量设置ID,同时保留onChange处理拖拽后的ID更新。

代码示例:

<script>
    import Sortable from "svelte-sortable";
    import { items } from "../store/links";
    import { onMount } from "svelte";

    const options = {
        animation: 150,
        dataIdAttr: "data-id",
        onChange: function (evt) {
            // 拖拽完成后更新所有元素的ID
            [].forEach.call(
                evt.from.getElementsByClassName("sortable_item"),
                function (el, index) {
                    el.setAttribute("id", index);
                }
            );
        },
    };

    onMount(() => {
        // 组件渲染完成后初始化ID
        const sortableItems = document.querySelectorAll(".sortable_item");
        sortableItems.forEach((el, index) => {
            el.setAttribute("id", index.toString());
        });
    });
</script>

<Sortable items={$items} let:item {options}>
    <div class="sortable_item">
        {item.item}
    </div>
</Sortable>

为什么onstart/onload不生效?

svelte-sortable封装了原生Sortable库,其初始化钩子(如onload)触发时,Svelte可能还未完成插槽内元素的渲染,导致无法获取到.sortable_item元素。而Svelte的onMount钩子会在组件及其子元素完全渲染后执行,能确保拿到所有目标元素。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 05:25:32