index.vue 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. <template>
  2. <movable-area class="drag-sort" :style="{height: currentListLength * height + 'px'}" id="drag">
  3. <movable-view
  4. v-for="(item, index) in currentList"
  5. :key="index"
  6. :x="0"
  7. :y="item.y"
  8. direction="vertical"
  9. disabled
  10. damping="40"
  11. :animation="active !== index"
  12. class="drag-sort-item"
  13. style="height:55px"
  14. :class="{'active': active === index, 'vh-1px-t': item.index > 0}">
  15. <view @click="label(item.label)" class="item-content" :class="avt==item.label?'act':''">{{item.label}}</view>
  16. <view class="touch-tight">
  17. <view class="ico_drag"></view>
  18. </view>
  19. </movable-view>
  20. <movable-view
  21. class="touch"
  22. :x="2000"
  23. @touchstart="touchstart"
  24. @touchmove="touchmove"
  25. @touchend="touchend"
  26. ></movable-view>
  27. </movable-area>
  28. </template>
  29. <script>
  30. export default {
  31. name: 'drag-sort',
  32. mixins: [],
  33. components: {},
  34. data () {
  35. return {
  36. height: 55, // 高度
  37. currentList: [],
  38. active: -1, // 当前激活的item
  39. itemIndex: 0, // 当前激活的item的原index
  40. topY: 0, // 距离顶部的距离
  41. deviationY: 0 ,// 偏移量
  42. avt:-1,
  43. }
  44. },
  45. computed: {
  46. currentListLength (){
  47. return 3
  48. }
  49. },
  50. props: {
  51. list: {
  52. type: Array,
  53. default: () => {
  54. return []
  55. }
  56. },
  57. props: {
  58. type: Object,
  59. default: () => {
  60. return {
  61. label: 'label',
  62. value: 'value'
  63. }
  64. }
  65. }
  66. },
  67. watch: {
  68. list (val) {
  69. this.onUpdateCurrentList()
  70. }
  71. },
  72. created () {
  73. this.onUpdateCurrentList()
  74. },
  75. mounted () {
  76. },
  77. updated () {},
  78. filters: {},
  79. methods: {
  80. onUpdateCurrentList () {
  81. let arr = []
  82. for (const key in this.list) {
  83. arr.push({
  84. ...this.list[key],
  85. index: Number(key),
  86. y: key * this.height,
  87. animation: true
  88. })
  89. }
  90. this.currentList = arr
  91. },
  92. touchstart (e) {
  93. // 计算y轴点击位置
  94. var query = wx.createSelectorQuery().in(this)
  95. query.select('#drag').boundingClientRect()
  96. query.exec((res) => {
  97. this.topY = res[0].top
  98. let touchY = e.mp.touches[0].clientY - res[0].top
  99. this.deviationY = touchY % this.height
  100. // console.log(touchY)
  101. for (const key in this.currentList) {
  102. if ((this.currentList[key].index * this.height < touchY) && ((this.currentList[key].index + 1) * this.height > touchY)) {
  103. this.active = Number(key)
  104. this.itemIndex = this.currentList[key].index
  105. break
  106. }
  107. }
  108. })
  109. },
  110. touchmove (e) {
  111. if (this.active < 0) return
  112. let touchY = (e.mp.touches[0].clientY - this.topY) - this.deviationY
  113. // console.log(touchY)
  114. this.currentList[this.active].y = touchY
  115. for (const key in this.currentList) {
  116. // 跳过当前操作的item
  117. if (this.currentList[key].index !== this.currentList[this.active].index) {
  118. if (this.currentList[key].index > this.currentList[this.active].index) {
  119. if (touchY > this.currentList[key].index * this.height - this.height / 2) {
  120. this.currentList[this.active].index = this.currentList[key].index
  121. this.currentList[key].index = this.currentList[key].index - 1
  122. this.currentList[key].y = this.currentList[key].index * this.height
  123. break
  124. }
  125. } else {
  126. if (touchY < this.currentList[key].index * this.height + this.height / 2) {
  127. this.currentList[this.active].index = this.currentList[key].index
  128. this.currentList[key].index = this.currentList[key].index + 1
  129. this.currentList[key].y = this.currentList[key].index * this.height
  130. break
  131. }
  132. }
  133. }
  134. }
  135. },
  136. touchend (e) {
  137. if ((this.itemIndex !== this.currentList[this.active].index) && (this.active > -1)) {
  138. this.$emit('change', {
  139. // 操作值
  140. data: (() => {
  141. let data = {
  142. ...this.currentList[this.active]
  143. }
  144. delete data.index
  145. delete data.y
  146. delete data.animation
  147. return data
  148. })(),
  149. // 插队的位置前面的值
  150. frontData: (() => {
  151. for (const iterator of this.currentList) {
  152. // console.log(iterator,"99")
  153. if (this.currentList[this.active].index - 1 === iterator.index) {
  154. let data = {
  155. ...iterator
  156. }
  157. delete data.index
  158. delete data.y
  159. delete data.animation
  160. return data
  161. }
  162. }
  163. })()
  164. })
  165. }
  166. this.currentList[this.active].animation = true
  167. this.currentList[this.active].y = this.currentList[this.active].index * this.height
  168. this.active = -1
  169. this.avt=-1
  170. },
  171. label(index){
  172. console.log(index,"dxc")
  173. this.avt=index;
  174. this.$emit('bindlabel',index)
  175. },
  176. }
  177. }
  178. </script>
  179. <style lang='less' scoped>
  180. @import "~./1px.less";
  181. .drag-sort {
  182. width: 100%;
  183. }
  184. .drag-sort-item {
  185. position: absolute !important;
  186. display: flex;
  187. align-items: center;
  188. width: 100%;
  189. padding: 0;
  190. margin: 0;
  191. background: #fff;
  192. padding: 0 15px;
  193. box-sizing: border-box;
  194. .item-content {
  195. flex: 1;
  196. margin-right: 40rpx;
  197. padding: 30rpx;
  198. border-radius: 4rpx;
  199. }
  200. .touch-tight {
  201. width: 24px;
  202. display: flex;
  203. justify-content: center;
  204. }
  205. }
  206. .drag-sort-item .act{
  207. background: #007AFF;
  208. color: #FFFFFF;
  209. }
  210. .touch {
  211. height: 100%;
  212. width: 50px;
  213. }
  214. .ico_drag {
  215. display: inline-block;
  216. width: 24px;
  217. height: 12px;
  218. background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAYCAYAAAC8/X7cAAAAAXNSR0IArs4c6QAAAEtJREFUWAnt1cEJACAMA0B1/506moIr5FEK51+Jl0d2Vd01+JzB2X90H5jeoPwECBDIBLYlzgDj25Y4JvQAAQIERgtY4u76LHF3Aw8rGQnK3sYAXQAAAABJRU5ErkJggg==) 0 0 no-repeat;
  219. background-size: 100% auto;
  220. }
  221. .active {
  222. box-shadow: 0 0 40rpx #DDDDDD;
  223. z-index: 99;
  224. }
  225. </style>