wk-drag-sort.vue 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. <template>
  2. <!-- Ŀǰ�汾��С����slot��������� -->
  3. <view class="wk-drag-sort">
  4. <view
  5. v-for="(item, index) in list"
  6. :id="`wk-drag-sort-item-` + index"
  7. :key="index"
  8. class="wk-drag-sort-item"
  9. @touchstart="handleTouchstart($event, index)"
  10. @touchmove.stop.prevent="handleTouchmove($event, index)"
  11. @touchend="handleTouchend($event, index)">
  12. <slot :scope-data="{ data: item, $index: index}" />
  13. </view>
  14. <view
  15. :style="{
  16. left: moveLeft + 'px',
  17. top: moveTop + 'px',
  18. width: itemWidth + 'px',
  19. height: itemHeight + 'px',
  20. visibility: showMoveItem ? 'unset' : 'hidden'
  21. }"
  22. class="move-item">
  23. <slot
  24. name="move"
  25. :data="moveItemData" />
  26. </view>
  27. </view>
  28. </template>
  29. <script>
  30. /**
  31. * ��ק����
  32. */
  33. import { deepCopy } from '@/utils/lib.js'
  34. export default {
  35. name: 'WkDragSort',
  36. props: {
  37. list: {
  38. type: Array,
  39. required: true
  40. },
  41. dealy: {
  42. type: Number,
  43. default: 100
  44. }
  45. },
  46. data() {
  47. return {
  48. allBoundary: [],
  49. moveItemData: {},
  50. activeIndex: -1,
  51. moveTop: 0,
  52. moveLeft: 0,
  53. itemWidth: 0,
  54. itemHeight: 0,
  55. showMoveItem: false,
  56. dealyTimer: null
  57. }
  58. },
  59. computed: {
  60. moveStyle() {
  61. return {
  62. left: this.moveLeft + 'px',
  63. top: this.moveTop + 'px',
  64. width: this.itemWidth + 'px',
  65. height: this.itemHeight + 'px',
  66. visibility: this.showMoveItem ? 'unset' : 'hidden'
  67. }
  68. }
  69. },
  70. watch: {
  71. list: {
  72. handler() {
  73. this.moveItemData = this.list[0]
  74. this.$nextTick(function() {
  75. this.getAllBoundary()
  76. })
  77. },
  78. deep: true,
  79. immediate: true
  80. },
  81. moveItemData: {
  82. handler() {
  83. this.$emit('set-move', this.moveItemData)
  84. },
  85. deep: true
  86. }
  87. },
  88. methods: {
  89. getAllBoundary() {
  90. const that = this
  91. uni.createSelectorQuery()
  92. .in(this)
  93. .selectAll('.wk-drag-sort-item')
  94. .boundingClientRect(data => {
  95. console.log('getAllBoundary: ', data)
  96. that.allBoundary = data.map(item => {
  97. return {
  98. ...item,
  99. beginX: item.left,
  100. endX: item.left + item.width,
  101. beginY: item.top,
  102. endY: item.top + item.height,
  103. }
  104. })
  105. })
  106. .exec();
  107. },
  108. handleTouchstart(evt, index) {
  109. if (this.dealyTimer) {
  110. clearTimeout(this.dealyTimer)
  111. this.dealyTimer = null
  112. }
  113. this.dealyTimer = setTimeout(() => {
  114. const query = uni.createSelectorQuery().in(this);
  115. query.select(`#wk-drag-sort-item-${index}`).boundingClientRect(data => {
  116. this.moveTop = data.top
  117. this.moveLeft = data.left
  118. this.moveItemData = this.list[index]
  119. this.activeIndex = index
  120. this.itemWidth = data.width
  121. this.itemHeight = data.height
  122. this.showMoveItem = true; // ������ʼ
  123. console.log('start move')
  124. clearTimeout(this.dealyTimer)
  125. this.dealyTimer = null
  126. }).exec();
  127. }, this.dealy)
  128. },
  129. handleTouchmove(evt, index) {
  130. const touch = evt.touches[0];
  131. this.moveLeft = touch.clientX - this.itemWidth / 2
  132. this.moveTop = touch.clientY - this.itemHeight / 2
  133. },
  134. handleTouchend(evt, index) {
  135. const overIndex = this.findOverIndex()
  136. if (overIndex !== -1) {
  137. const arr = deepCopy(this.list)
  138. arr[overIndex] = arr.splice(this.activeIndex, 1, arr[overIndex])[0]
  139. console.log('sort: ', arr)
  140. this.$emit('sort', arr)
  141. }
  142. this.showMoveItem = false // ��������
  143. this.activeIndex = -1
  144. this.moveLeft = 0
  145. this.moveTop = 0
  146. },
  147. // �ҵ�ͣ�µ�Ԫ�ص��±�
  148. findOverIndex() {
  149. for (let i = 0; i < this.allBoundary.length; i++) {
  150. const item = this.allBoundary[i]
  151. if (
  152. this.moveLeft > item.beginX &&
  153. this.moveLeft < item.endX &&
  154. this.moveTop > item.beginY &&
  155. this.moveTop < item.endY
  156. ) {
  157. return i
  158. }
  159. }
  160. return -1
  161. }
  162. }
  163. }
  164. </script>
  165. <style scoped lang="scss">
  166. .wk-drag-sort {
  167. .wk-drag-sort-item {}
  168. .move-item {
  169. position: fixed;
  170. visibility: hidden;
  171. z-index: 10;
  172. }
  173. }
  174. </style>