当前位置:首页 > vue实现一个简单的拖拽排序组件

vue实现一个简单的拖拽排序组件

发布于 2020-05-14 阅读 1917 次 Javascript

想做一个排序功能就想到了拖拽,自己做了一个可以满足基本需求的demo

主要用到了drag的两个事件
dragstart
dragover

思路就是,首先有一个数组数据,dragstart的时候记录下拖动的元素数据在数组中的下标,dargover的时候记录下放置元素的下标,然后通过splice方法改变数组。

下面是封装的组件主要代码:

这是是个列表,可以把它当做一个空的表格的感觉,具体表格内容需要通过slot的方式传入

  1. <template>
  2. <div>
  3. <el-switch v-model="draggable" active-text="拖拽排序" inactive-text="禁止排序"></el-switch>
  4. <div class="z-nav-list">
  5. <div
  6. :class="'z-nav-wrap '+(draggable ? 'draggable' :'')"
  7. v-for="(item, index) in list"
  8. :key="item.id"
  9. :index="index"
  10. @dragover="dragover($event, index)"
  11. >
  12. <a href="javascript:;"
  13. :draggable="draggable"
  14. @dragstart="dragstart($event, index)"
  15. @dragend="dragend()"
  16. >
  17. <slot v-bind:row="item"></slot>
  18. </a>
  19. </div>
  20. </div>
  21. </div>
  22. </template>
  23. <script>
  24. import { deepClone } from '@/utils/tool';
  25. export default{
  26. props: {
  27. data: {
  28. type: Array,
  29. default: () => []
  30. }
  31. },
  32. data() {
  33. return {
  34. oldPosition: 0,//拖拽元素 index
  35. newPutPosition: 0,//拖拽 放入元素index,放入后变成拖拽元素的index
  36. draggable: false
  37. }
  38. },
  39. computed: {
  40. list: {
  41. get() {
  42. let data = deepClone(this.data);
  43. data.forEach((v, k) => {
  44. v.index = k;
  45. });
  46. return data;
  47. },
  48. set() {
  49. }
  50. }
  51. },
  52. methods: {
  53. dragstart(e, index) {
  54. if(!this.draggable) return false;
  55. // this.target = e.currentTarget;
  56. this.oldPosition = index;
  57. },
  58. dragend(index) {
  59. if(!this.draggable) return false;
  60. },
  61. dragover(e, index) {
  62. if(!this.draggable) return false;
  63. e.preventDefault();
  64. this.newPutPosition = index;
  65. if(this.oldPosition != this.newPutPosition) {
  66. let item = this.list.splice(this.oldPosition, 1);
  67. this.list.splice(this.newPutPosition, 0, item[0]);
  68. this.oldPosition = this.newPutPosition;
  69. this.$emit('change', this.list);
  70. }
  71. }
  72. }
  73. }
  74. </script>