index.vue 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. <script setup lang="ts">
  2. import { ref, onMounted } from "vue";
  3. import draggable from "vuedraggable/src/vuedraggable";
  4. import { useRenderIcon } from "/@/components/ReIcon/src/hooks";
  5. defineOptions({
  6. name: "Draggable"
  7. });
  8. let gridLists = ref<Array<Object>>([
  9. { grid: "cn", num: 1 },
  10. { grid: "cn", num: 2 },
  11. { grid: "cn", num: 3 },
  12. { grid: "cn", num: 4 },
  13. { grid: "cn", num: 5 },
  14. { grid: "cn", num: 6 },
  15. { grid: "cn", num: 7 },
  16. { grid: "cn", num: 8 },
  17. { grid: "cn", num: 9 }
  18. ]);
  19. let lists = ref<Array<Object>>([
  20. { people: "cn", id: 1, name: "www.itxst.com" },
  21. { people: "cn", id: 2, name: "www.baidu.com" },
  22. { people: "cn", id: 3, name: "www.taobao.com" },
  23. { people: "cn", id: 4, name: "www.google.com" }
  24. ]);
  25. let cutLists = ref([
  26. { people: "cn", id: 1, name: "cut1" },
  27. { people: "cn", id: 2, name: "cut2" },
  28. { people: "cn", id: 3, name: "cut3" },
  29. { people: "cn", id: 4, name: "cut4" }
  30. ]);
  31. const change = (evt): void => {
  32. console.log("evt: ", evt);
  33. };
  34. onMounted(() => {
  35. // 使用原生sortable实现元素位置切换
  36. // @ts-ignore
  37. new Sortable(document.querySelector(".cut-container"), {
  38. swap: true,
  39. forceFallback: true,
  40. chosenClass: "chosen",
  41. swapClass: "highlight",
  42. animation: 300
  43. });
  44. });
  45. </script>
  46. <template>
  47. <el-card>
  48. <template #header>
  49. <div class="card-header">
  50. <span>
  51. 拖拽组件,采用开源的
  52. <el-link
  53. href="https://sortablejs.github.io/vue.draggable.next/#/simple"
  54. target="_blank"
  55. :icon="useRenderIcon('rank')"
  56. style="font-size: 16px; margin: 0 4px 5px"
  57. >
  58. vuedraggable
  59. </el-link>
  60. </span>
  61. </div>
  62. </template>
  63. <div class="drag-container">
  64. <!-- grid列表拖拽 -->
  65. <el-row :gutter="25">
  66. <el-col :xs="25" :sm="8" :md="8" :lg="8">
  67. <el-card>
  68. <template #header>
  69. <div class="card-header">
  70. <span>grid列表拖拽</span>
  71. </div>
  72. </template>
  73. <draggable
  74. v-model="gridLists"
  75. class="grid-container"
  76. item-key="grid"
  77. animation="300"
  78. chosenClass="chosen"
  79. forceFallback="true"
  80. >
  81. <template #item="{ element }">
  82. <div :class="'item' + ' ' + 'item-' + element.num">
  83. {{ element.num }}
  84. </div>
  85. </template>
  86. </draggable>
  87. </el-card>
  88. </el-col>
  89. <el-col :xs="25" :sm="8" :md="8" :lg="8">
  90. <el-card>
  91. <template #header>
  92. <div class="card-header">
  93. <span>单列拖拽</span>
  94. </div>
  95. </template>
  96. <!-- 单列拖拽 -->
  97. <draggable
  98. v-model="lists"
  99. item-key="name"
  100. @change="change"
  101. chosen-class="chosen"
  102. force-fallback="true"
  103. animation="300"
  104. >
  105. <template #item="{ element, index }">
  106. <div class="item-single">{{ element.name }} {{ index }}</div>
  107. </template>
  108. </draggable>
  109. </el-card>
  110. </el-col>
  111. <el-col :xs="25" :sm="8" :md="8" :lg="8">
  112. <el-card>
  113. <template #header>
  114. <div class="card-header">
  115. <span>拖拽实现元素位置切换</span>
  116. </div>
  117. </template>
  118. <!-- 拖拽实现元素位置切换 -->
  119. <div class="cut-container">
  120. <div
  121. class="item-cut"
  122. v-for="(item, index) in cutLists"
  123. :key="index"
  124. >
  125. <p>{{ item.name }}</p>
  126. </div>
  127. </div>
  128. </el-card>
  129. </el-col>
  130. </el-row>
  131. </div>
  132. </el-card>
  133. </template>
  134. <style lang="scss" scoped>
  135. /* grid列表拖拽 */
  136. .grid-container {
  137. display: grid;
  138. grid-template-columns: 33.3% 33.3% 33.3%;
  139. grid-template-rows: 33.3% 33.3% 33.3%;
  140. }
  141. .item-single {
  142. font-size: 1.5em;
  143. height: 77px;
  144. text-align: center;
  145. line-height: 85px;
  146. border: 1px solid #e5e4e9;
  147. cursor: move;
  148. }
  149. .item-cut {
  150. font-size: 1.5em;
  151. height: 77px;
  152. line-height: 77px;
  153. text-align: center;
  154. border: 1px solid #e5e4e9;
  155. cursor: move;
  156. }
  157. .item {
  158. font-size: 2em;
  159. text-align: center;
  160. line-height: 100px;
  161. border: 1px solid #e5e4e9;
  162. cursor: move;
  163. @media screen and (max-width: 750px) {
  164. line-height: 90px;
  165. }
  166. }
  167. .item-1 {
  168. background-color: #ef342a;
  169. }
  170. .item-2 {
  171. background-color: #f68f26;
  172. }
  173. .item-3 {
  174. background-color: #4ba946;
  175. }
  176. .item-4 {
  177. background-color: #0376c2;
  178. }
  179. .item-5 {
  180. background-color: #c077af;
  181. }
  182. .item-6 {
  183. background-color: #f8d29d;
  184. }
  185. .item-7 {
  186. background-color: #b5a87f;
  187. }
  188. .item-8 {
  189. background-color: #d0e4a9;
  190. }
  191. .item-9 {
  192. background-color: #4dc7ec;
  193. }
  194. .chosen {
  195. border: solid 2px #3089dc !important;
  196. }
  197. </style>