告别繁琐排序!Layui穿梭框拖拽排序与自定义排序全攻略

告别繁琐排序!Layui穿梭框拖拽排序与自定义排序全攻略

【免费下载链接】layui 一套遵循原生态开发模式的 Web UI 组件库,采用自身轻量级模块化规范,易上手,可以更简单快速地构建网页界面。 【免费下载链接】layui 项目地址: https://gitcode.com/GitHub_Trending/la/layui

你还在为穿梭框(Transfer)排序功能头疼吗?客户要求拖拽调整顺序、运营需要按业务优先级排序,开发却找不到现成方案?本文将带你用10行核心代码实现两种排序方案,轻松解决90%的排序场景需求。读完你将掌握:拖拽排序实现原理、自定义排序规则配置、排序状态持久化技巧。

为什么需要排序功能?

在后台管理系统中,穿梭框常用于角色权限分配、商品分类管理等场景。默认的穿梭框仅支持左右移动,无法调整顺序,导致:

  • 运营人员需要按重要性手动记录顺序
  • 前端展示时无法体现业务优先级
  • 数据提交后顺序混乱,影响下游系统处理

官方文档明确说明基础穿梭框组件不包含排序功能,需要通过扩展实现:docs/transfer/index.md

拖拽排序实现方案

核心原理

通过监听穿梭框的onchange事件,结合原生JavaScript的拖拽API,实现右侧列表的拖拽排序。关键步骤:

  1. 初始化穿梭框时添加拖拽属性
  2. 监听拖拽开始、移动、结束事件
  3. 交换DOM位置并更新数据源

完整代码示例

<div id="transfer-sort-demo"></div>

<script>
layui.use(['transfer', 'jquery'], function(){
  var transfer = layui.transfer;
  var $ = layui.jquery;
  
  // 初始化数据
  var data = [
    {"value": "1", "title": "产品经理"},
    {"value": "2", "title": "UI设计师"},
    {"value": "3", "title": "前端开发"},
    {"value": "4", "title": "后端开发"},
    {"value": "5", "title": "测试工程师"}
  ];
  
  // 渲染穿梭框
  transfer.render({
    elem: '#transfer-sort-demo',
    data: data,
    value: ["2", "3"], // 初始右侧数据
    title: ['待选角色', '已选角色'],
    onchange: function(data, index){
      // 只处理右侧列表排序
      if(index === 1) initDragSort();
    }
  });
  
  // 初始化拖拽排序
  function initDragSort(){
    var items = $('.layui-transfer-list:last .layui-transfer-item');
    items.attr('draggable', true)
      .on('dragstart', function(e){
        e.dataTransfer.setData('text/plain', $(this).index());
      })
      .on('dragover', function(e){
        e.preventDefault();
      })
      .on('drop', function(e){
        e.preventDefault();
        var fromIndex = parseInt(e.dataTransfer.getData('text/plain'));
        var toIndex = $(this).index();
        var list = $('.layui-transfer-list:last .layui-transfer-content');
        var items = list.find('.layui-transfer-item');
        
        // 交换DOM位置
        if(fromIndex < toIndex){
          items.eq(fromIndex).insertAfter(items.eq(toIndex));
        }else{
          items.eq(fromIndex).insertBefore(items.eq(toIndex));
        }
        
        // 更新数据源(实际项目中应保存到数据库)
        console.log('新顺序:', getSortedValues());
      });
  }
  
  // 获取排序后的值
  function getSortedValues(){
    var values = [];
    $('.layui-transfer-list:last .layui-transfer-item').each(function(){
      values.push($(this).data('value'));
    });
    return values;
  }
});
</script>

实现要点

  1. 拖拽事件绑定:通过draggable属性开启拖拽能力,监听dragstartdragoverdrop三个关键事件
  2. DOM操作:使用jQuery的insertBeforeinsertAfter方法实现元素位置交换
  3. 数据同步:通过getSortedValues方法实时获取排序后的value数组,用于表单提交

组件核心源码位于:src/modules/transfer.js,可通过修改源码实现更复杂的排序需求。

自定义排序规则实现

适用场景

当拖拽排序无法满足业务需求时(如按拼音、创建时间排序),可通过自定义排序函数实现。常见排序规则:

  • 按标题字母/拼音排序
  • 按数值大小排序
  • 按创建时间倒序
  • 按自定义权重排序

按标题拼音排序示例

// 拼音排序函数
function sortByPinyin(a, b) {
  return a.title.localeCompare(b.title, 'zh-CN');
}

// 应用排序
transfer.render({
  elem: '#transfer-sort-custom',
  data: data,
  value: ["1", "2", "3"],
  onchange: function(data, index){
    if(index === 1){
      // 获取右侧当前数据
      var rightData = transfer.getData('sort-custom-id');
      // 按拼音排序
      rightData.sort(sortByPinyin);
      // 重载组件更新排序
      transfer.reload('sort-custom-id', {
        value: rightData.map(item => item.value)
      });
    }
  }
});

按自定义权重排序

// 权重配置
var weightMap = {
  "产品经理": 3,
  "前端开发": 2,
  "后端开发": 1,
  "UI设计师": 4,
  "测试工程师": 5
};

// 权重排序函数
function sortByWeight(a, b) {
  return weightMap[a.title] - weightMap[b.title];
}

排序状态持久化

本地存储方案

使用localStorage保存排序状态,适合单用户场景:

// 保存排序
function saveSortState(values){
  localStorage.setItem('transferSortState', JSON.stringify(values));
}

// 读取排序
function getSortState(){
  return JSON.parse(localStorage.getItem('transferSortState') || '[]');
}

// 使用示例
transfer.render({
  elem: '#transfer-sort-persist',
  data: data,
  value: getSortState(), // 初始值从本地存储读取
  onchange: function(data, index){
    if(index === 1){
      saveSortState(getSortedValues());
    }
  }
});

后端存储方案

对于多用户协作场景,需要将排序结果提交到后端:

// 提交排序到后端
function submitSortState(values){
  $.ajax({
    url: '/api/save-sort',
    method: 'POST',
    data: {values: values.join(',')},
    success: function(res){
      console.log('排序已保存');
    }
  });
}

常见问题解决方案

问题1:拖拽后数据不同步

原因:DOM位置变化后未更新组件的内部数据模型
解决:每次拖拽结束后调用transfer.getData(id)获取最新数据

问题2:大量数据拖拽卡顿

优化方案

  1. 使用虚拟滚动减少DOM节点
  2. 拖拽时隐藏非相关元素
  3. 使用CSS3硬件加速:transform: translateZ(0)

问题3:与搜索功能冲突

解决方案:在搜索事件中重新初始化拖拽排序:

// 监听搜索框输入
$('.layui-transfer-search').on('input', function(){
  setTimeout(initDragSort, 100); // 延迟执行,等待DOM更新
});

总结与扩展

通过本文介绍的两种方案,你可以轻松实现Layui穿梭框的排序功能:

  • 拖拽排序适合需要直观调整顺序的场景
  • 自定义排序适合有固定规则的业务需求

进阶学习建议:

  1. 查看官方高级示例:docs/transfer/examples/
  2. 研究组件源码:src/modules/transfer.js
  3. 尝试实现多级排序(如先按类型再按名称)

希望本文能帮你解决排序难题,让穿梭框组件发挥更大价值!如果觉得有用,别忘了点赞收藏,关注作者获取更多Layui实用技巧。

【免费下载链接】layui 一套遵循原生态开发模式的 Web UI 组件库,采用自身轻量级模块化规范,易上手,可以更简单快速地构建网页界面。 【免费下载链接】layui 项目地址: https://gitcode.com/GitHub_Trending/la/layui

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值