前军教程网

中小站长与DIV+CSS网页布局开发技术人员的首选CSS学习平台

拖拽排序组件——在Vue3项目中轻松实现组件的拖拽排序功能

介绍

在Web端做组件拖拽功能在当下的各类项目中不足为奇,因为我们拥有非常不错的第三方组件供我们使用,让我们实现这样的功能变得非常简单轻松,今天就介绍一个在Vue3中使用的一个拖拽排序组件——vue.draggable.next,它是SortableJS官方基于SortableJS针对Vue3开发的一个拖拽排序组件!从它Github的主页来看,官方实现了在各个框架(包括原生js)的JavaScript库,相信很多小伙伴或多或少都用过!




特点

  • 完全支持Sortable.js特性

包括触摸设备、拖动手柄和可选文本、智能自动滚动、支持不同列表间的拖放、不依赖 jQuery

  • 保持 HTML 响应式数据列表的同步
  • 兼容 Vue.js 3.0 过渡组
  • 取消已经可拖拽的组件
  • 完全控制任何更改的事件
  • 重用现有的 UI 库组件(vuetify, element, 以及vue material等等)并使用 tag 和 componentData 道具使它们可拖动

安装使用

下面我们直接安装体验一番,这里我们可以使用npm或者yarn进行安装,笔者相较于习惯yarn

yarn add vuedraggable@next
npm i -S vuedraggable@next

下面是笔者录制的一个Gif图:

//代码示例
<template>
  <div class="wrap">
    <draggable
      v-model="list"
      @start="drag = true"
      @end="drag = false"
      item-key="id"
    >
      <template #item="{ element }">
        <div class="drag">{{ element.name }}</div>
      </template>
    </draggable>
  </div>
</template>
<script lang="ts">
import { defineComponent, ref } from "vue";
import draggable from "vuedraggable";
export default defineComponent({
  name: "VueDrag",
  components: {
    draggable,
  },
  setup() {
    const drag = ref(false);
    const list = ref([
      {
        name: "茅檐长扫净无苔",
        id: 0,
      },
      {
        name: "花木成畦手自栽",
        id: 1,
      },
      {
        name: "一水护田将绿绕",
        id: 2,
      },
      {
        name: "两山排闼送青来",
        id: 3,
      },
    ]);
    return { drag, list };
  },
});
</script>

<style scoped>
.wrap {
  margin-top: 500px;
  margin-left: 900px;
  width: 800px;
  text-align: center;
  border: 1px rebeccapurple solid;
  padding: 20px;
}

.drag {
  background-color: cadetblue;
  color: aliceblue;
  font-size: 28px;
  height: 48px;
  line-height: 48px;
  border: 1px royalblue solid;
  border-radius: 6px;
  margin: 10px;
}
</style>

我们可以看到是以slot插槽(slot-props)的方式实现的。

  • 在两个不同的拖拽组件间相互拖拽

group属性设为一致

<div class="l1">
      <h3>列表1</h3>
      <draggable class="list-group" :list="list1" group="tangsh" itemKey="name">
        <template #item="{ element, index }">
          <div>{{ element.name }}</div>
        </template>
      </draggable>
    </div>

    <div class="l2">
      <h3>列表2</h3>
      <draggable class="list-group" :list="list2" group="tangsh" itemKey="name">
        <template #item="{ element, index }">
          <div>{{ element.name }}</div>
        </template>
      </draggable>
    </div>
  • 动画效果演示
<template>
  <div class="row">
    <div class="col-6">
      <h3>动画效果</h3>
      <draggable
        class="list-group"
        tag="transition-group"
        :component-data="{
          tag: 'ul',
          type: 'transition-group',
          name: !drag ? 'flip-list' : null,
        }"
        v-model="list"
        v-bind="dragOptions"
        @start="drag = true"
        @end="drag = false"
        item-key="order"
      >
        <template #item="{ element }">
          <div class="list-group-item">
            <i
              :class="
                element.fixed ? 'fa fa-anchor' : 'glyphicon glyphicon-pushpin'
              "
              @click="element.fixed = !element.fixed"
              aria-hidden="true"
            ></i>
            {{ element.name }}
          </div>
        </template>
      </draggable>
    </div>

  </div>
</template>

<script>
import draggable from "vuedraggable";
const message = ["春眠不觉晓,", "处处闻啼鸟。", "夜来风雨声,", "花落知多少。"];
export default {
  display: "Transitions",
  order: 7,
  components: {
    draggable,
  },
  data() {
    return {
      list: message.map((name, index) => {
        return { name, order: index + 1 };
      }),
      drag: false,
    };
  },
  methods: {
    sort() {
      this.list = this.list.sort((a, b) => a.order - b.order);
    },
  },
  computed: {
    dragOptions() {
      return {
        animation: 200,
        group: "description",
        disabled: false,
        ghostClass: "ghost",
      };
    },
  },
};
</script>

<style>

.flip-list-move {
  transition: transform 0.5s;
}
.no-move {
  transition: transform 0s;
}
.ghost {
  opacity: 0.5;
  background: #c8ebfb;
}
.list-group {
  margin-left: 800px;
  margin-top: 300px;
  min-height: 20px;
}
.list-group-item {
  cursor: move;
  background-color: cadetblue;
  height: 48px;
  width: 600px;
  margin-top: 10px;
  line-height: 48px;
  color: #c8ebfb;
  font-size: 24px;
}
.list-group-item i {
  cursor: pointer;
}
</style>

总结

本文只是简单介绍几个例子,官方中还介绍了其它一些更加复杂的操作,包括在表格行和列的拖拽等等操作,使用它都不是难事,官网针对每一个例子都有完整的代码演示,使用起来相当的简单,如果你有类似的需求,则可以尝试使用它来实现你想要的效果,希望对你有所帮助!

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言