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
相关产品推荐
相关产品推荐

