本网站(662p.com)打包出售,且带程序代码数据,662p.com域名,程序内核采用TP框架开发,需要联系扣扣:2360248666 /wx:lianweikj
精品域名一口价出售:1y1m.com(350元) ,6b7b.com(400元) , 5k5j.com(380元) , yayj.com(1800元), jiongzhun.com(1000元) , niuzen.com(2800元) , zennei.com(5000元)
需要联系扣扣:2360248666 /wx:lianweikj
vue实现拖拽排序效果
mylove136 · 178浏览 · 发布于2022-08-30 +关注

这篇文章主要为大家详细介绍了vue实现拖拽排序效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了vue实现拖拽排序效果的具体代码,供大家参考,具体内容如下

效果预览

组件 drag.vue

<template>
  <TransitionGroup name="group-list" tag="ul">
    <li
      v-for="(item, index) in list"
      :key="item.name"
      :draggable="item.draggable"
      :class="[
        'list-item',
        {
          'is-dragover':
            index === dropIndex && item.draggable && config.exchange,
        },
      ]"
      @dragstart="onDragstart($event, index)"
      @dragenter="onDragenter(index)"
      @dragover.prevent="onDragover(index)"
      @dragleave="onDragleave"
      @dragend="onDragend"
      @drop="onDrop"
    >
      <slot :item="item" />
    </li>
  </TransitionGroup>
</template>
 
<script>
export default {
  name: "Draggable",
  props: {
    list: {
      type: Array,
      default: () => [],
    },
    config: {
      type: Object,
      default: () => ({
        name: "",
        push: true,
        pull: true,
        exchange: true,
      }),
    },
  },
 
  data() {
    return {
      dragIndex: null,
      dropIndex: null,
    };
  },
 
  computed: {
    isPush() {
      const { dropIndex, dragIndex } = this;
      return dropIndex !== null && dragIndex === null;
    },
 
    isExchange() {
      const { dropIndex, dragIndex } = this;
      return dragIndex !== null && dropIndex !== null;
    },
 
    pushCbName() {
      const {
        config: { name },
      } = this;
      return `${name}-push-callback`;
    },
  },
 
  methods: {
    onDragstart(e, i) {
      const {
        list,
        config: { name },
        transferData,
      } = this;
 
      this.dragIndex = i;
 
      if (name) {
        transferData({ e, key: name, type: "set", data: list[i] });
      } else {
        throw new Error("缺少配置关联名name");
      }
 
      this.$emit("drag-start", i);
    },
 
    onDragenter(i) {
      this.dropIndex = i;
      this.$emit("drag-enter", i);
    },
 
    onDragover(i) {
      const { dragIndex, dropIndex } = this;
      if (i === dragIndex || i === dropIndex) return;
      this.dropIndex = i;
      this.$emit("drag-over", i);
    },
 
    onDragleave() {
      this.dropIndex = null;
    },
 
    onDrop(e) {
      const {
        list,
        dropIndex,
        dragIndex,
        config: { name, push: enablePush, exchange },
        isPush,
        isExchange,
        pushCbName,
        storage,
        resetIndex,
        transferData,
      } = this;
 
      if (dropIndex === dragIndex || !exchange) return;
 
      if (isPush) {
        if (!enablePush) {
          resetIndex();
          return;
        }
 
        if (name) {
          list.splice(
            dropIndex,
            0,
            transferData({ e, key: name, type: "get" })
          );
 
          storage("set", pushCbName, true);
        } else {
          resetIndex();
          throw new Error("缺少配置关联属性name");
        }
        resetIndex();
        return;
      }
 
      if (isExchange) {
        const drapItem = list[dragIndex];
        const dropItem = list[dropIndex];
        list.splice(dropIndex, 1, drapItem);
        list.splice(dragIndex, 1, dropItem);
      }
 
      resetIndex();
    },
 
    onDragend() {
      const {
        list,
        dragIndex,
        config: { pull: enablePull },
        pushCbName,
        storage,
        resetIndex,
      } = this;
 
      if (enablePull) {
        const isPushSuccess = storage("get", pushCbName);
 
        if (isPushSuccess) {
          list.splice(dragIndex, 1);
          storage("remove", pushCbName);
        }
      }
      resetIndex();
      this.$emit("drag-end");
    },
 
    storage(type, key, value) {
      return {
        get() {
          return JSON.parse(localStorage.getItem(key));
        },
        set() {
          localStorage.setItem(key, JSON.stringify(value));
        },
        remove() {
          localStorage.removeItem(key);
        },
      }[type]();
    },
 
    resetIndex() {
      this.dropIndex = null;
      this.dragIndex = null;
    },
 
    transferData({ e, key, type, data } = {}) {
      if (type === "get") {
        return JSON.parse(e.dataTransfer.getData(`${key}-drag-key`));
      }
 
      if (type === "set") {
        e.dataTransfer.setData(`${key}-drag-key`, JSON.stringify(data));
      }
    },
  },
};
</script>
 
<style  scoped>
.list-item {
  list-style: none;
  position: relative;
  margin-bottom: 10px;
  border-radius: 4px;
  padding: 4px;
  background-color: #fff;
  cursor: move;
}
 
.list-item.is-dragover::before {
  content: "";
  position: absolute;
  bottom: -4px;
  left: 0;
  width: 100%;
  height: 4px;
  background-color: #0c6bc9;
}
 
.list-item.is-dragover::after {
  content: "";
  position: absolute;
  bottom: -8px;
  left: -6px;
  border: 3px solid #0c6bc9;
  border-radius: 50%;
  width: 6px;
  height: 6px;
  background-color: #fff;
}
 
.group-list-move {
  transition: transform 0.8s;
}
</style>

使用范例

index.vue

<template>
  <div class="dragBox">
    <Drag style="width: 200px" :list="list1" :config="config1">
      <template v-slot="{ item }">
        <div class="item">
          {{ item.name }}
        </div>
      </template>
    </Drag>
     <Drag style="width: 200px" :list="list2" :config="config2">
      <template v-slot="{ item }">
        <div class="item">
          {{ item.name }}
        </div>
      </template>
    </Drag>
  </div>
</template>
 <script>
import Drag from "./drag.vue";
 export default {
  components: {
    Drag,
  },
   data() {
    return {
      list1: new Array(10).fill(0).map((_, i) => ({
        name: `列表1 - ${i + 1}`,
        draggable: true,
      })),
       config1: {
        name: "test",
        push: true,
        pull: true,
        exchange: true,
      },
       list2: new Array(10).fill(0).map((_, i) => ({
        name: `列表2 - ${i + 1}`,
        draggable: true,
      })),
       config2: {
        name: "test",
        push: true,
        pull: true,
        exchange: true,
      },
    };
  },
};
</script>
 <style  scoped>
.dragBox {
  display: flex;
  justify-content: center;
}
.item {
  border: 1px solid #ccc;
  width: 200px;
  height: 30px;
  text-align: center;
}
</style>

参数说明

list: 渲染列表
config: {
    name: '', // 跨列表关联名,跨列表拖拽时必传
    push: true, // 当前列表是否支持从其他列表push元素进来
    pull: true, // 将当前列表的某个元素拖拽并添加到其他列表里,该元素是否从当前列表移除
    exchange: true, // 当前列表元素之间是否支持交换位置
}



相关推荐

PHP实现部分字符隐藏

沙雕mars · 1325浏览 · 2019-04-28 09:47:56
Java中ArrayList和LinkedList区别

kenrry1992 · 908浏览 · 2019-05-08 21:14:54
Tomcat 下载及安装配置

manongba · 970浏览 · 2019-05-13 21:03:56
JAVA变量介绍

manongba · 962浏览 · 2019-05-13 21:05:52
什么是SpringBoot

iamitnan · 1086浏览 · 2019-05-14 22:20:36
加载中

0评论

评论
分类专栏
小鸟云服务器
扫码进入手机网页