ToB企服应用市场:ToB评测及商务社交产业平台

标题: vue编写一个可拖动的模块,并可以和任何其他组件组合使用 [打印本页]

作者: 道家人    时间: 12 小时前
标题: vue编写一个可拖动的模块,并可以和任何其他组件组合使用
实现思路
代码示例
  1. <template>
  2.   <div v-draggable class="draggable-component">
  3.     <slot></slot>
  4.   </div>
  5. </template>
  6. <script>
  7. export default {
  8.   name: 'DraggableComponent',
  9.   directives: {
  10.     draggable: {
  11.       // 当绑定元素插入到 DOM 中时
  12.       mounted(el) {
  13.         let isDragging = false;
  14.         let initialX, initialY;
  15.         let offsetX = 0, offsetY = 0;
  16.         const handleMouseDown = (e) => {
  17.           isDragging = true;
  18.           initialX = e.clientX - offsetX;
  19.           initialY = e.clientY - offsetY;
  20.         };
  21.         const handleMouseMove = (e) => {
  22.           if (isDragging) {
  23.             offsetX = e.clientX - initialX;
  24.             offsetY = e.clientY - initialY;
  25.             el.style.transform = `translate3d(${offsetX}px, ${offsetY}px, 0)`;
  26.           }
  27.         };
  28.         const handleMouseUp = () => {
  29.           isDragging = false;
  30.         };
  31.         el.addEventListener('mousedown', handleMouseDown);
  32.         document.addEventListener('mousemove', handleMouseMove);
  33.         document.addEventListener('mouseup', handleMouseUp);
  34.         // 在元素销毁时移除事件监听器
  35.         el._removeEventListeners = () => {
  36.           el.removeEventListener('mousedown', handleMouseDown);
  37.           document.removeEventListener('mousemove', handleMouseMove);
  38.           document.removeEventListener('mouseup', handleMouseUp);
  39.         };
  40.       },
  41.       unmounted(el) {
  42.         if (el._removeEventListeners) {
  43.           el._removeEventListeners();
  44.         }
  45.       }
  46.     }
  47.   }
  48. };
  49. </script>
  50. <style scoped>
  51. .draggable-component {
  52.   position: absolute;
  53.   background-color: #f0f0f0;
  54.   border: 1px solid #ccc;
  55.   padding: 10px;
  56.   cursor: move;
  57. }
  58. </style>
复制代码
代码解释

使用示例
  1. <template>
  2.   <div id="app">
  3.     <DraggableComponent>
  4.       <h1>可拖动的组件</h1>
  5.       <p>这是一个可以拖动的模块,并且可以和任何其他组件组合使用。</p>
  6.       <AnotherComponent></AnotherComponent>
  7.     </DraggableComponent>
  8.   </div>
  9. </template>
  10. <script>
  11. import DraggableComponent from './DraggableComponent.vue';
  12. import AnotherComponent from './AnotherComponent.vue';
  13. export default {
  14.   name: 'App',
  15.   components: {
  16.     DraggableComponent,
  17.     AnotherComponent
  18.   }
  19. };
  20. </script>
复制代码
解释

留意事项

通过上述方法,你可以在 Vue 中实现一个可拖动的模块,并将其与任何其他组件举行组合使用。如果你需要更复杂的拖动功能,例如与其他组件举行交互或支持多个可拖动元素,可以考虑使用第三方库,如 vue-draggable 或 vue-draggable-resizable。这些库提供了更丰富的功能和更强盛的拖动、调整大小等操作。
还有其他方法实现可拖动模块吗?

另一种在 Vue 中实现可拖动模块的方法,使用 Vue 的 ref 和组件方法来处理拖动逻辑:
实现思路
代码示例
  1. <template>
  2.   <div ref="draggable" class="draggable-component">
  3.     <slot></slot>
  4.   </div>
  5. </template>
  6. <script>
  7. export default {
  8.   name: 'DraggableComponent',
  9.   data() {
  10.     return {
  11.       isDragging: false,
  12.       startX: 0,
  13.       startY: 0,
  14.       offsetX: 0,
  15.       offsetY: 0
  16.     };
  17.   },
  18.   mounted() {
  19.     const draggable = this.$refs.draggable;
  20.     const handleMouseDown = (e) => {
  21.       this.isDragging = true;
  22.       this.startX = e.clientX - this.offsetX;
  23.       this.startY = e.clientY - this.offsetY;
  24.     };
  25.     const handleMouseMove = (e) => {
  26.       if (this.isDragging) {
  27.         this.offsetX = e.clientX - this.startX;
  28.         this.offsetY = e.clientY - this.startY;
  29.         draggable.style.transform = `translate3d(${this.offsetX}px, ${this.offsetY}px, 0)`;
  30.       }
  31.     };
  32.     const handleMouseUp = () => {
  33.       this.isDragging = false;
  34.     };
  35.     draggable.addEventListener('mousedown', handleMouseDown);
  36.     document.addEventListener('mousemove', handleMouseMove);
  37.     document.addEventListener('mouseup', handleMouseUp);
  38.     // 在组件销毁时移除事件监听器
  39.     this.$once('hook:beforeDestroy', () => {
  40.       draggable.removeEventListener('mousedown', handleMouseDown);
  41.       document.removeEventListener('mousemove', handleMouseMove);
  42.       document.removeEventListener('mouseup', handleMouseUp);
  43.     });
  44.   }
  45. };
  46. </script>
  47. <style scoped>
  48. .draggable-component {
  49.   position: absolute;
  50.   background-color: #f0f0f0;
  51.   border: 1px solid #ccc;
  52.   padding: 10px;
  53.   cursor: move;
  54. }
  55. </style>
复制代码
代码解释

使用示例
  1. <template>
  2.   <div id="app">
  3.     <DraggableComponent>
  4.       <h1>可拖动的组件</h1>
  5.       <p>这是另一种实现可拖动模块的方式,可以与其他组件组合使用。</p>
  6.       <AnotherComponent></AnotherComponent>
  7.     </DraggableComponent>
  8.   </div>
  9. </template>
  10. <script>
  11. import DraggableComponent from './DraggableComponent.vue';
  12. import AnotherComponent from './AnotherComponent.vue';
  13. export default {
  14.   name: 'App',
  15.   components: {
  16.     DraggableComponent,
  17.     AnotherComponent
  18.   }
  19. };
  20. </script>
复制代码
第三种方法:使用 Vue 3 的 Composition API 和 onMounted、onUnmounted
如果你使用 Vue 3,还可以使用 Composition API 来实现:
  1. <template>
  2.   <div ref="draggable" class="draggable-component">
  3.     <slot></slot>
  4.   </div>
  5. </template>
  6. <script>
  7. import { ref, onMounted, onUnmounted } from 'vue';
  8. export default {
  9.   name: 'DraggableComponent',
  10.   setup() {
  11.     const draggable = ref(null);
  12.     let isDragging = ref(false);
  13.     let startX = ref(0);
  14.     let startY = ref(0);
  15.     let offsetX = ref(0);
  16.     let offsetY = ref(0);
  17.     const handleMouseDown = (e) => {
  18.       isDragging.value = true;
  19.       startX.value = e.clientX - offsetX.value;
  20.       startY.value = e.clientY - offsetY.value;
  21.     };
  22.     const handleMouseMove = (e) => {
  23.       if (isDragging.value) {
  24.         offsetX.value = e.clientX - startX.value;
  25.         offsetY.value = e.clientY - startY.value;
  26.         draggable.value.style.transform = `translate3d(${offsetX.value}px, ${offsetY.value}px, 0)`;
  27.       }
  28.     };
  29.     const handleMouseUp = () => {
  30.       isDragging.value = false;
  31.     };
  32.     onMounted(() => {
  33.       if (draggable.value) {
  34.         draggable.value.addEventListener('mousedown', handleMouseDown);
  35.         document.addEventListener('mousemove', handleMouseMove);
  36.         document.addEventListener('mouseup', handleMouseUp);
  37.       }
  38.     });
  39.     onUnmounted(() => {
  40.       if (draggable.value) {
  41.         draggable.value.removeEventListener('mousedown', handleMouseDown);
  42.         document.removeEventListener('mousemove', handleMouseMove);
  43.         document.removeEventListener('mouseup', handleMouseUp);
  44.       }
  45.     });
  46.     return {
  47.       draggable
  48.     };
  49.   }
  50. };
  51. </script>
  52. <style scoped>
  53. .draggable-component {
  54.   position: absolute;
  55.   background-color: #f0f0f0;
  56.   border: 1px solid #ccc;
  57.   padding: 10px;
  58.   cursor: move;
  59. }
  60. </style>
复制代码
代码解释

这些方法都可以实现可拖动模块,你可以根据自己的喜欢和项目使用的 Vue 版本选择合适的实现方式。如果你需要更复杂的拖动功能,例如拖动排序、拖动边界限定、与其他组件交互等,大概需要进一步扩展上述代码或使用第三方库,如 vue-draggable 或 vue-draggable-resizable。
你可以将上述代码复制到相应的 Vue 文件中举行测试和使用,根据自己的需求举行修改和扩展。如果还有其他需求,例如限定拖动范围或添加更多的交互功能,可以进一步细化上述代码或向我提出更具体的问题。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4