Обмен технологиями

В мобильном терминале uniapp реализован сбор товаров методом перетаскивания, а также функция смахивания влево для удаления нескольких товаров подряд!

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Я давно его не видел. Недавно познакомился с продуктом. Это был его первый раз, когда он делал продукт. Всегда есть какие-то античеловеческие замыслы. Правильно, это коллекция перетаскивания по заголовку и смахивание левой кнопкой мыши для удаления продукта. Просматривая все основные приложения, я не нашел ни одного с такой функцией. Он все время говорил, что покажет мне его после использования, я долго ждал, может он забыл.

Столкнувшись с такого рода спросом, я также попытался связаться с ним, например, использовать корзину для удаления продуктов и т. д., а также изменить некоторую логику, которую каждый может принять, но у него были свои идеи, и мне пришлось выбрать уважайте это.

1. Функция сбора перетаскиванием

После долгих поисков функции перетаскивания коллекции я использовал плагин перетаскивания, написанный мастером, и адаптировал его соответствующим образом, поскольку мое требование требует отображения не коллекции, а страницы. подпрыгивает при сборе, поэтому будут некоторые модификации, но в целом они похожи. Вот официальный сайт плагина.

vue.draggable документация на китайском языке — itxst.com

Примечание. Во время разработки при отслеживании событий начала и окончания перетаскивания будет сообщаться об ошибке. Если это так, рекомендуется решить ее самостоятельно или использовать тот же метод, что и я, для мониторинга процесса перетаскивания и т. д. Это зависит от того. на потребностях. Прикрепите код в конце:

  1. <template>
  2. <div id="app">
  3. <h1>商品列表</h1>
  4. <div class="container">
  5. <div class="row">
  6. <!-- @change="onDragEnd" @start="start" @end="onEnd" :move="onMove" delay="1000" -->
  7. <div class="col-md-6">
  8. <draggable v-model="leftItems" :group="group" delay="1000"
  9. @change="onDragEnd" :move="onMove"
  10. animation="300" dragClass="dragClass" ghostClass="ghostClass">
  11. <!-- <u-swipe-action :show="item.show" :index="index"
  12. v-for="(item, index) in leftItems" :key="item.id"
  13. @click="click" @open="open"
  14. :options="options"
  15. > -->
  16. <div class="item" v-for="(item, index) in leftItems" :key="item.id" >{{ item.name }}</div>
  17. <!-- </u-swipe-action> -->
  18. </draggable>
  19. </div>
  20. <div class="col-md-6">
  21. <draggable v-model="rightItems" :group="group"
  22. @change="onDragEnd" :move="onMove">
  23. <div v-for="(item, index) in rightItems" :key="index" @longpress="aaa(index)" :class="['item',item.status==true?'shake':'']">{{ item.name }}</div>
  24. </draggable>
  25. </div>
  26. </div>
  27. </div>
  28. </div>
  29. </template>
  30. <script>
  31. import draggable from 'vuedraggable';
  32. export default {
  33. components: {
  34. draggable
  35. },
  36. data() {
  37. return {
  38. disabled: false,
  39. btnWidth: 180,
  40. show: false,
  41. options: [
  42. {
  43. text: '删除',
  44. style: {
  45. backgroundColor: '#dd524d'
  46. }
  47. }
  48. ],
  49. timerId: null,//计时器id
  50. group: {
  51. name: "itxst",
  52. pull: true, //可以拖出
  53. put: true, //可以拖入
  54. },
  55. leftItems: [{
  56. id: 1,
  57. show: false,
  58. status: false,
  59. name: '商品1'
  60. },
  61. {
  62. id: 2,
  63. show: false,
  64. status: false,
  65. name: '商品2'
  66. },
  67. {
  68. id: 3,
  69. show: false,
  70. status: false,
  71. name: '商品3'
  72. },
  73. {
  74. id: 4,
  75. show: false,
  76. status: false,
  77. name: '商品4'
  78. },
  79. {
  80. id: 5,
  81. show: false,
  82. status: false,
  83. name: '商品5'
  84. },
  85. {
  86. id: 6,
  87. show: false,
  88. status: false,
  89. name: '商品6'
  90. },
  91. ],
  92. rightItems: [{
  93. id: 1,
  94. show: false,
  95. status: false,
  96. name: '商品1'
  97. },
  98. {
  99. id: 2,
  100. show: false,
  101. status: false,
  102. name: '商品2'
  103. },
  104. {
  105. id: 3,
  106. show: false,
  107. status: false,
  108. name: '商品3'
  109. },
  110. {
  111. id: 4,
  112. show: false,
  113. status: false,
  114. name: '商品4'
  115. },
  116. {
  117. id: 5,
  118. show: false,
  119. status: false,
  120. name: '商品5'
  121. },
  122. {
  123. id: 6,
  124. show: false,
  125. status: false,
  126. name: '商品6'
  127. },
  128. ]
  129. };
  130. },
  131. onLoad() {
  132. },
  133. methods: {
  134. click(index) {
  135. this.leftItems.splice(index, 1);
  136. this.$u.toast(`删除了第${index}个cell`);
  137. },
  138. // 如果打开一个的时候,不需要关闭其他,则无需实现本方法
  139. open(index) {
  140. // 先将正在被操作的swipeAction标记为打开状态,否则由于props的特性限制,
  141. // 原本为false,再次设置为false会无效
  142. this.leftItems[index].show = true;
  143. this.leftItems.map((val, idx) => {
  144. if(index != idx) this.leftItems[idx].show = false;
  145. })
  146. },
  147. start(e) {
  148. console.log(e, 'kasihi ');
  149. },
  150. onEnd() {
  151. console.log(e, '结束了 ');
  152. },
  153. onMove(e) { // keyi huanyuan
  154. clearTimeout(this.timerId)
  155. console.log('如果能监听到要在这里清楚计时器');
  156. return this.canFormSet()
  157. },
  158. aaa(index) {
  159. this.rightItems[index].status = true
  160. this.timerId = setTimeout(() => {
  161. this.rightItems[index].status = false
  162. clearTimeout(this.timerId)
  163. }, 500)
  164. },
  165. onDragEnd(event) {
  166. console.log(event);
  167. // if (event.newIndex !== event.oldIndex) {
  168. // const movedItem = this.leftItems[event.oldIndex];
  169. // this.leftItems.splice(event.oldIndex, 1);
  170. // this.rightItems.push(movedItem);
  171. // 判断是否可以形成集合跳转页面
  172. if (this.canFormSet()) {
  173. // 跳转到另一个页面的逻辑
  174. console.log('路由去往新的页面');
  175. // this.$router.push('/another-page');
  176. } else {
  177. // 如果不能形成集合,则复原
  178. console.log('复原');
  179. // this.rightItems.pop();
  180. // this.leftItems.splice(event.newIndex, 0, movedItem);
  181. }
  182. console.log('6666');
  183. clearTimeout(this.timerId)
  184. // } else {
  185. // console.log('else');
  186. // // Revert the move if it's not a valid combination
  187. // const movedItem = this.rightItems.pop();
  188. // this.leftItems.splice(event.newIndex, 0, movedItem);
  189. // }
  190. },
  191. canFormSet() {
  192. // 如果可以形成集合,返回 true;否则返回 false
  193. return false; // 示例中默认返回 true
  194. }
  195. }
  196. };
  197. </script>
  198. <style scoped lang="scss">
  199. .shake {
  200. width: 100px;
  201. height: 100px;
  202. background-color: red;
  203. transform-origin: center;
  204. animation: shake .5s infinite ease-in-out;
  205. }
  206. @keyframes shake {
  207. 0%,
  208. 100% {
  209. transform: rotate(-5deg);
  210. /* transform: translate(-50%, -50%) rotate(-5deg); */
  211. }
  212. 50% {
  213. transform: rotate(5deg);
  214. }
  215. }
  216. .ghostClass {
  217. background-color: blue !important;
  218. }
  219. .chosenClass {
  220. background-color: red !important;
  221. opacity: 1 !important;
  222. }
  223. .dragClass {
  224. background-color: blueviolet !important;
  225. opacity: 1 !important;
  226. box-shadow: none !important;
  227. outline: none !important;
  228. background-image: none !important;
  229. }
  230. .container {
  231. width: 100%;
  232. margin-top: 20px;
  233. }
  234. .row {
  235. width: 100%;
  236. display: flex;
  237. }
  238. .col-md-6 {
  239. width: 100%;
  240. // display: flex;
  241. // flex-wrap: wrap;
  242. }
  243. .item {
  244. width: 100px;
  245. height: 100px;
  246. margin-left: 20px;
  247. border: 1px solid #ccc;
  248. padding: 10px;
  249. margin-bottom: 10px;
  250. background-color: #f9f9f9;
  251. }
  252. </style>

2. Функция скользящего удаления нескольких товаров в одной строке.

Все видели приведенный выше код, и я планирую его использовать. u-swipe-действие для реализации функции скользящего удаления, но она может перемещать и удалять только одну строку. Итак, я взглянул на исходный код, а затем меня осенило: я вручную закодировал код эффекта удаления из нескольких строк. В будущем я также проведу некоторую оптимизацию. ваша ссылка, надеюсь, она вам поможет:

  1. <template>
  2. <view class="container">
  3. <movable-area class="box-info"
  4. v-for="(item, index) in items"
  5. :key="index">
  6. <movable-view
  7. style="width: 140px; height: 100px; background-color: #aa55ff;"
  8. :style="{widh}"
  9. :x="index * 10"
  10. :direction="'horizontal'"
  11. :out-of-bounds="false"
  12. >
  13. <view class="product">
  14. <view style="width: 100px;">{{item}}</view>
  15. <view class="move" @click="removeShop">删除</view>
  16. </view>
  17. </movable-view>
  18. </movable-area>
  19. </view>
  20. </template>
  21. <script>
  22. export default {
  23. data() {
  24. return {
  25. items: ['商品1', '商品2']
  26. };
  27. },
  28. methods: {
  29. removeShop(index) {
  30. alert('删除商品操作')
  31. }
  32. }
  33. };
  34. </script>
  35. <style scoped lang="scss">
  36. .container {
  37. display: flex;
  38. justify-content: center;
  39. align-items: center;
  40. height: 100%;
  41. .box-info {
  42. display: flex;
  43. flex-wrap: wrap;
  44. height: 100px;
  45. width: 100px;
  46. background-color: #55ff7f;
  47. overflow: hidden;
  48. margin: 20px;
  49. .product {
  50. display: flex;
  51. justify-content: center;
  52. align-items: center;
  53. font-size: 14px;
  54. color: #333;
  55. .move{
  56. background-color: #55aa00;
  57. width: 40px;
  58. height: 100px;
  59. writing-mode: vertical-rl;
  60. display: flex;
  61. justify-content: center;
  62. align-items: center;
  63. }
  64. }
  65. }
  66. }
  67. </style>