# Dragsort 拖拽排序 3.4.64

dragsort 拖拽排序组件,支持垂直、水平和网格三种模式的拖拽排序,适用于列表重排、九宫格排序等场景。

# 平台差异说明

App(vue) App(nvue) H5 小程序
x

# 基本使用

  • 通过 initialList 设置初始数据列表
  • 通过 [direction]设置拖拽方向:vertical(垂直)、horizontal(水平)、all(网格)
  • 通过 [columns] 设置网格模式下的列数
  • 通过 [draggable] 控制是否允许拖拽
<template>
  <view class="p-4 bg-white">
    <!-- 垂直拖拽排序 -->
    <up-dragsort 
      :initialList="verticalList" 
      direction="vertical"
      @drag-end="onVerticalDragEnd"
    />
    
    <!-- 水平拖拽排序 -->
    <up-dragsort 
      :initialList="horizontalList" 
      direction="horizontal"
      class="mt-4"
      @drag-end="onHorizontalDragEnd"
    />
    
    <!-- 网格拖拽排序 -->
    <up-dragsort 
      :initialList="gridList" 
      direction="all"
      :columns="3"
      class="mt-4"
      @drag-end="onGridDragEnd"
    />
  </view>
</template>

<script>
export default {
  data() {
    return {
      verticalList: [
        { id: 1, label: '项目1' },
        { id: 2, label: '项目2' },
        { id: 3, label: '项目3' },
        { id: 4, label: '项目4' }
      ],
      horizontalList: [
        { id: 1, label: '项目A' },
        { id: 2, label: '项目B' },
        { id: 3, label: '项目C' },
        { id: 4, label: '项目D' }
      ],
      gridList: [
        { id: 1, label: '格子1' },
        { id: 2, label: '格子2' },
        { id: 3, label: '格子3' },
        { id: 4, label: '格子4' },
        { id: 5, label: '格子5' },
        { id: 6, label: '格子6' }
      ]
    }
  },
  methods: {
    onVerticalDragEnd(list) {
      console.log('垂直拖拽结束', list);
      this.verticalList = list;
    },
    onHorizontalDragEnd(list) {
      console.log('水平拖拽结束', list);
      this.horizontalList = list;
    },
    onGridDragEnd(list) {
      console.log('网格拖拽结束', list);
      this.gridList = list;
    }
  }
}
</script>

# 高级用法示例

# 1. 部分项目禁用拖拽

可以通过给列表项添加 draggable: false 属性来禁用特定项目的拖拽功能:

<up-dragsort 
  :initialList="listWithFixedItems" 
  direction="vertical"
  @drag-end="onDragEnd"
>
  <template #default="{ item, index }">
    <view class="custom-item" :class="{ 'fixed-item': item.draggable === false }">
      <text>{{ item.label }}</text>
      <text v-if="item.draggable === false" class="fixed-label">(固定)</text>
    </view>
  </template>
</up-dragsort>

<script>
export default {
  data() {
    return {
      listWithFixedItems: [
        { id: 1, label: '可拖拽项目1', draggable: true },
        { id: 2, label: '固定项目', draggable: false },
        { id: 3, label: '可拖拽项目2', draggable: true },
        { id: 4, label: '可拖拽项目3', draggable: true }
      ]
    }
  }
}
</script>

# 2. 自定义网格样式

网格模式下可以实现图标类应用的拖拽排序:

<up-dragsort 
  :initialList="appList" 
  direction="all"
  :columns="4"
  @drag-end="onDragEnd"
>
  <template #default="{ item, index }">
    <view class="app-item">
      <view class="app-icon">
        <text>{{ item.icon }}</text>
      </view>
      <text class="app-label">{{ item.label }}</text>
    </view>
  </template>
</up-dragsort>

<script>
export default {
  data() {
    return {
      appList: [
        { id: 1, label: '电话', icon: '📞' },
        { id: 2, label: '短信', icon: '💬' },
        { id: 3, label: '相机', icon: '📷' },
        { id: 4, label: '设置', icon: '⚙️' },
        { id: 5, label: '音乐', icon: '🎵' },
        { id: 6, label: '视频', icon: '🎬' }
      ]
    }
  }
}
</script>

<style>
.app-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 10px;
}

.app-icon {
  font-size: 24px;
  margin-bottom: 5px;
}

.app-label {
  font-size: 12px;
}
</style>

# 3. 响应式列数

根据不同屏幕尺寸调整网格列数:

<up-dragsort 
  :initialList="responsiveList" 
  direction="all"
  :columns="gridColumns"
  @drag-end="onDragEnd"
>
  <template #default="{ item }">
    <view class="grid-item">
      <text>{{ item.label }}</text>
    </view>
  </template>
</up-dragsort>

<script>
export default {
  data() {
    return {
      responsiveList: [
        { id: 1, label: '项目1' },
        { id: 2, label: '项目2' },
        { id: 3, label: '项目3' },
        // ...更多项目
      ]
    }
  },
  computed: {
    gridColumns() {
      // 根据屏幕宽度动态计算列数
      const screenWidth = uni.getSystemInfoSync().windowWidth;
      if (screenWidth < 375) {
        return 2; // 小屏手机
      } else if (screenWidth < 414) {
        return 3; // 中屏手机
      } else {
        return 4; // 大屏手机/平板
      }
    }
  }
}
</script>

# 自定义内容

通过默认插槽可以自定义每个拖拽项的内容:

<up-dragsort 
  :initialList="customList" 
  direction="vertical"
  @drag-end="onCustomDragEnd"
>
  <template #default="{ item, index }">
    <view class="custom-item">
      <text>{{ index + 1 }}. {{ item.label }}</text>
    </view>
  </template>
</up-dragsort>

# 演示页面源代码地址

点击以下链接以查看演示页面的源码


 github  gitee

# API

# Props

参数 说明 类型 默认值 可选值
initialList 初始数据列表 Array []
draggable 是否允许拖拽 Boolean true false
direction 拖拽方向 String vertical vertical / horizontal / all
columns all模式下的列数 Number 3

# Events

事件名 说明 回调参数
drag-end 拖拽结束时触发 排序后的列表

# Slot

名称 说明
default 自定义每个拖拽项的内容,参数为 { item, index }