VueDraggableNext实现简单表格拖拽

1,147 阅读1分钟

image.png

  1. 下载依赖
npm install vue-draggable-next
//or
yarn add vue-draggable-next
  1. 引入
import { VueDraggableNext } from 'vue-draggable-next'
components: {
   draggable: VueDraggableNext,
},
  1. 使用
  <div class="app-container">
    <table class="tableDraggable" v-loading="listLoading">
      <tr class="tableDraggable-header">
        <th class="minWidth10">Name</th>
        <th class="minWidth50">Title</th>
        <th class="minWidth40">Author</th>
      </tr>
      <draggable :list="list" handle=".handle" @change="log" ghostClass="sortable-ghost">
        <tr v-for="item in list" :key="item.id" class="tableDraggable-body">
          <td class="minWidth10">
            {{ item.id }}
          </td>
          <td class="minWidth50">
            {{ item.title }}
          </td>
          <td class="minWidth40 handle">
            {{ item.author }}
          </td>
        </tr>
      </draggable>
    </table>
  </div>
</template>

<script lang="ts">
import { defineComponent, reactive, onMounted, toRefs } from "vue";
import { ArticleModel } from "@/model/articleModel";
import { getArticles } from "@/apis/articles";
import { VueDraggableNext } from "vue-draggable-next";
export default defineComponent({
  components: {
    draggable: VueDraggableNext,
  },
  setup() {
    const dataMap = reactive({
      list: Array<ArticleModel>(),
      listLoading: true,
      total: 0,
      listQuery: {
        page: 1,
        limit: 10,
      },
      async getList() {
        dataMap.listLoading = true;
        const data = await getArticles(this.listQuery);
        dataMap.list = data?.data.items ?? [];
        setTimeout(() => {
          dataMap.listLoading = false;
        }, 0.5 * 1000);
        dataMap.total = data?.data.total ?? 0;
      },
    });
    onMounted(() => {
      dataMap.getList();
    });
    return { ...toRefs(dataMap) };
  },
  methods: {
    log(event: any) {
      console.log(event);
    },
  },
});
</script>

<style lang="scss" scoped>
::v-deep .tableDraggable {
  .sortable-ghost {
    opacity: 0.8;
    color: #fff !important;
    background: #42b983 !important;
  }
  display: block;
  width: 100%;
  .minWidth10 {
    width: 10%;
  }
  .minWidth40 {
    width: 40%;
  }
  .minWidth50 {
    width: 50%;
  }
  .handle {
    cursor: pointer;
  }
  &-header {
    display: flex;
    width: 100%;
    text-align: left;
    th {
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
  }
  &-body {
    display: flex;
    width: 100%;
    margin-top: 10px;
    td {
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      margin-top: 10px;
    }
  }
}
</style>
  1. 其他

handle=".handle" 移动列的class

ghostClass="sortable-ghost" 样式

链接 www.npmjs.com/package/vue…