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

tom-select使用drag-drop插件时如何保留拖拽自定义排序顺序

问题根因

tom-select 初始化时默认会对已选中的选项执行内置排序规则(默认按文本字母序排列),即使你已经把拖拽调整后的顺序存入数据库,只要初始化时没有显式指定已选项的渲染顺序,组件就会按默认规则重排已选值,导致自定义顺序丢失。

实现步骤

全程不需要修改拖拽插件的源码,只需要调整初始化配置和数据加载逻辑即可,同时可以保留下拉选项按字母排序的原有效果:

  • 提前预处理加载数据
    从后端拉取两类数据:全量下拉选项列表、当前字段已选中的值数组。注意已选值数组必须是数据库中存储的、按拖拽调整后的顺序排列的原始数组,不要在前端做任何排序处理。
  • 调整初始化配置,禁用已选项自动排序
    初始化时不要依赖原生select的selected属性自动识别已选值(原生option默认按字母序渲染,会打乱顺序),显式传入按自定义顺序排列的已选值数组,同时关闭组件全局默认排序,单独给下拉面板保留字母排序逻辑,参考配置:
// 实例化tom-select
const selectIns = new TomSelect('#multi-select', {
  plugins: ['drag_drop'], // 保留原有拖拽插件
  // 核心配置:关闭全局自动排序,已选项严格按传入的items顺序渲染
  sortField: null,
  // 传入按自定义顺序排好的已选值数组
  items: orderedSelectedValuesFromDB,
  // 传入全量下拉选项
  options: allOptionsFromDB,
  // 单独给下拉面板的选项设置字母排序,不影响已选标签的顺序
  onDropdownOpen: function() {
    const optionNodes = Array.from(this.dropdown_content.querySelectorAll('.option'))
    optionNodes.sort((prev, next) => prev.textContent.localeCompare(next.textContent))
    optionNodes.forEach(node => this.dropdown_content.appendChild(node))
  }
})
  • 校验拖拽后的顺序存储逻辑
    确保拖拽调整顺序后,你存入数据库的是组件实例返回的原始顺序数组,不要做额外排序处理:
// 监听拖拽排序完成事件,拿到最新顺序存库
selectIns.on('drop', () => {
  const latestOrder = selectIns.items
  // 调用后端接口,将latestOrder原样存入数据库即可
})
// 新增选项时也同步更新顺序
selectIns.on('item_add', () => {
  const latestOrder = selectIns.items
  // 同步存库
})

避坑提示:不要在页面渲染时提前输出带selected属性的原生option标签,否则tom-select初始化时会优先读取DOM里的option顺序,覆盖你通过items配置传入的自定义顺序。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 14:15:53