列表拖拽修改顺序

<template>
  <div class="drag-sort-container">
    <h2>拖拽排序示例</h2>
    <ul id="sortable-list">
      <li 
        v-for="item in items" 
        :key="item.id" 
        :data-id="item.id"
        draggable="true"
        @dragstart="handleDragStart($event, item)"
        @dragenter="handleDragEnter($event, item)"
        @dragover="handleDragOver($event)"
        @dragleave="handleDragLeave($event, item)"
        @drop="handleDrop($event, item)"
        @dragend="handleDragEnd($event)"
        :class="{ 'dragging': draggingItem === item, 'over': overItem === item }"
      >
        {{ item.name }}
      </li>
    </ul>
    <button @click="saveOrder">保存顺序</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [
        { id: 1, name: '项目 1' },
        { id: 2, name: '项目 2' },
        { id: 3, name: '项目 3' },
        { id: 4, name: '项目 4' },
        { id: 5, name: '项目 5' }
      ],
      draggingItem: null,
      overItem: null
    };
  },
  methods: {
    handleDragStart(e, item) {
      this.draggingItem = item;
      e.dataTransfer.effectAllowed = 'move';
      e.dataTransfer.setData('text/plain', item.id);
    },
    handleDragOver(e) {
      e.preventDefault(); // 必须阻止默认行为才能触发drop事件
      e.dataTransfer.dropEffect = 'move';
      return false;
    },
    handleDragEnter(e, item) {
      e.preventDefault();
      if (this.draggingItem !== item) {
        this.overItem = item;
      }
    },
    handleDragLeave(e, item) {
      if (this.overItem === item) {
        this.overItem = null;
      }
    },
    handleDrop(e, item) {
      e.stopPropagation();
      e.preventDefault();
      
      if (this.draggingItem !== item) {
        // 找到当前拖拽项和目标项的索引
        const srcIndex = this.items.indexOf(this.draggingItem);
        const targetIndex = this.items.indexOf(item);
        
        // 创建新数组,避免直接修改原数组
        const newItems = [...this.items];
        // 移除拖拽项
        const [removedItem] = newItems.splice(srcIndex, 1);
        // 插入拖拽项到目标位置
        newItems.splice(targetIndex, 0, removedItem);
        
        // 更新数据
        this.items = newItems;
      }
      
      this.overItem = null;
      return false;
    },
    handleDragEnd() {
      this.draggingItem = null;
      this.overItem = null;
    },
    saveOrder() {
      // 获取当前排序的ID数组
      const order = this.items.map(item => item.id);
      console.log('新的顺序:', order);
      
      // 这里可以添加实际的保存逻辑,比如调用API
      // this.$http.post('/save-order', { order })
      //   .then(response => {
      //     console.log('保存成功', response.data);
      //   })
      //   .catch(error => {
      //     console.error('保存失败', error);
      //   });
    }
  }
};
</script>

<style scoped>
.drag-sort-container {
  font-family: sans-serif;
  padding: 20px;
}

#sortable-list {
  list-style: none;
  padding: 0;
  width: 300px;
  margin: 0 auto;
}

#sortable-list li {
  padding: 10px 15px;
  margin-bottom: 8px;
  background: #f0f0f0;
  border: 1px solid #ddd;
  cursor: move;
  user-select: none;
}

/* 拖拽时样式 */
.dragging {
  opacity: 0.5;
}

.over {
  border-top: 2px solid #007bff;
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猛男敲代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

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

抵扣说明:

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

余额充值