This article shares the specific code of Vue to implement multi-column layout drag for your reference. The specific content is as follows 1. ObjectivesVue implements free dragging and width change of multiple boxes (users decide the number of boxes based on actual scenarios). 2. Application ScenariosMulti-column layout with freely draggable width. The most typical case: editor (eg: vscode, idea, etc.) Component DesignSince the number of boxes of this component is uncertain, we referred to the design of Form and FormItem in Vuetify when designing the component. That is, the outer large box handles the distributed drag events, and the inner box is responsible for displaying the contents of each Item. Component design achieves the following goals: <drag-box style="width: 100%; height: 100%;"> <drag-item>item1</drag-item> <drag-item>item2</drag-item> <drag-item>item3</drag-item> <drag-item>item4</drag-item> </drag-box> 4. Implementation4.1 dragBox static page (Nesting of sub-elements is achieved through slots) <template> <div ref='dragBox' style='display: flex; width: 100%; height: 100%;'> <slot></slot> </div> </template> 4.2 dragItem page (Nesting of drag-item internal elements is achieved through slots) <template> <div ref="container" class="d-flex" style="min-width: 200px; position: relative;"> <div style="width: 100%; height: 100%;"> <slot>Default information</slot> </div> <!-- Drag bar --> <div v-if="resizeShow" class="resize" /> </div> </template> <script> export default { props: { // Controls whether the drag bar is displayed, the default is to display resizeShow: { type: Boolean, default: true } } } </script> <style> .resize { position: absolute; top: 0; right: 0; width: 4px; height: 100%; cursor: col-resize; background-color: #d6d6d6; } </style> 4.3 Drag Logic The drag logic should be handled by dragBox, not dragItem. 4.3.1 Before implementing dragging, child elements (i.e. dragItem) should be properly laid out. When the user does not assign an initial width to the dragItem , the default flex:1 is used (the remaining space is evenly distributed). The specific logic is as follows: // If dragItem does not define width, flex=1 setDragItemFlex () { const dragBox = this.$refs.dragBox const childrenLen = dragBox.children.length for (let i = 0; i < childrensLen; i++) { const node = dragBox.children[i] if (!node.style.width) { // If width is not defined, flex=1 node.style.flex = 1 } } }, 4.3.2 Drag and drop implementation logic Drag events should be added for each dragItem's drag bar. The complete drag event includes: mouse press, mouse move, and mouse lift (end of dragging). Loop to add events for each drag bar: dragControllerDiv () { const resize = document.getElementsByClassName('resize') // Drag bar // Loop to add events for each drag bar for (let i = 0; i < resize.length; i++) { // Mouse press event resize[i].addEventListener('mousedown', this.onMouseDown) } }, Mouse press logic: Get the initial position of the mouse, change the color of the drag bar, and add listener events for move and up. onMouseDown (e) { this.resizeBox = e.target this.currentBox = this.resizeBox.parentNode // Current box this.rightBox = this.getNextElement(this.currentBox) // Next sibling node of the current box if (!this.rightBox) return this.curLen = this.currentBox.clientWidth this.otherBoxWidth = this.$refs.dragBox.clientWidth - this.currentBox.clientWidth - this.rightBox.clientWidth // Width of other boxes // Color change reminder this.resizeBox.style.background = '#818181' this.startX = e.clientX document.addEventListener('mousemove', this.onMousemove) document.addEventListener('mouseup', this.onMouseup) }, // Get the next sibling element compatible function getNextElement (element) { if (element.nextElementSibling) { return element.nextElementSibling } else { var next = element.nextSibling // Next sibling node while (next && next.nodeType !== 1) { // It exists and it's not what I want next = next.nextSibling } return next } } Mouse move event: Calculate and set the width of the current box and the right box. onMousemove (e) { const endX = e.clientX const moveLen = endX - this.startX // (endx-startx) = moving distance const CurBoxLen = this.curLen + moveLen // resize[i].left + moving distance = final width of the left area const rightBoxLen = this.$refs.dragBox.clientWidth - CurBoxLen - this.otherBoxWidth // Right width = total width - left width - other box width // When the minimum width is reached, dragging is unavailable if (CurBoxLen <= 200 || rightBoxLen <= 200) return this.currentBox.style.width = CurBoxLen + 'px' // Current box width this.resizeBox.style.left = CurBoxLen // Set the width of the left area this.rightBox.style.width = rightBoxLen + 'px' }, Mouse up event: destroy mousedown and mousemove events; restore the color of the drag bar. onMouseup () { // Color restoration this.resizeBox.style.background = '#d6d6d6' document.removeEventListener('mousedown', this.onMouseDown) document.removeEventListener('mousemove', this.onMousemove) }, Add corresponding events in the mounted hook function. mounted () { this.setDragItemFlex() this.dragControllerDiv() }, Import and register the component: <template> <div id="app" style="width: 100%; height: 100vh; border:1px solid #ccc;"> <drag-box style="width: 100%; height: 100%;"> <drag-item style="width: 20%;">item1</drag-item> <drag-item>item2</drag-item> <drag-item style="width: 20%;" :resizeShow='false'>item3</drag-item> </drag-box> </div> </template> <script> import {DragBox, DragItem} from './components/dragLayouter' export default { name: 'App', components: DragBox, DragItem } } </script> 5. Operation ResultsThe specific style can be modified later. The above is the full content of this article. I hope it will be helpful for everyone’s study. I also hope that everyone will support 123WORDPRESS.COM. You may also be interested in:
|
<<: Teach you how to build Tencent Cloud Server (graphic tutorial)
>>: How to verify whether MySQL is installed successfully
Tips for viewing History records and adding times...
In SQL, GROUP BY is used to group data in the res...
Table of contents design Component Communication ...
The download address of FlashFXP is: https://www....
[Solution 1: padding implementation] principle: I...
Preface: Partitioning is a table design pattern. ...
Table of contents 1. Development Environment 2. I...
Table of contents Preface Related Materials Vue p...
1. Background In actual projects, we will encount...
The code looks like this: .process{ border:1px so...
Download the installation package from the offici...
Without relying on JavaScript, pure CSS is used t...
Here we introduce the knowledge about form elemen...
In the development environment, the vue project i...
MySQL is a relational database management system ...