Drag Directive
v-tui-drag is a general-purpose drag enhancement directive in TechUI. It allows developers to turn any DOM element into a draggable state via a configuration object. This directive not only supports conventional absolute positioning dragging but is also deeply optimized for the transform performance mode and features built-in coordinate correction logic for large-screen scaling scenarios (Adaptive).
Core Features
- Dual Mode Positioning: Supports two movement modes:
transform(GPU accelerated, default) andstyle.left/top(Absolute positioning). - Fine-grained Control: Supports specifying a drag handle (
trigger) and excluded areas (exclude). - Boundary Constraints: Automatically restricts element movement within the parent container's scope (
containment). - Scale Adaptation: Built-in
inAdptparameter to solve the issue of desynchronization between mouse displacement and element movement under the large-screenscalemode.
Basic Usage
The simplest usage is to bind the directive directly. It enables containment and uses transform for movement by default.
<template>
<div class="box" v-tui-drag>
Drag Me
</div>
</template>API Reference
v-tui-drag accepts an object as a parameter, supporting the following configuration options:
| Parameter Name | Description | Type | Default |
|---|---|---|---|
| enabled | Enable Switch. Controls whether dragging is allowed. It automatically handles cursor styles when dynamically switched. | Boolean | true |
| trigger | Drag Handle. CSS selector string. Dragging is triggered only when the mouse is pressed on the specified child element (e.g., allow dragging only by holding the title bar). | String | el (Self) |
| exclude | Excluded Area. CSS selector string. Elements located inside the trigger that do not trigger dragging (e.g., the close button on the title bar). | String | — |
| containment | Boundary Constraint. Whether to restrict the element within the visible range of the parent container. | Boolean | true |
| positionType | Positioning Mode. Options: 'transform' or 'absolute'/'fixed'. 'transform': Modifies CSS Translate, better performance, does not break document flow. 'absolute': Modifies left/top, suitable for traditional positioning layouts. | String | 'transform' |
| inAdpt | Scale Correction. Whether it is inside a TechUI scaling adaptive container. When enabled, it corrects mouse coordinates based on the global tDom.adpt.info to prevent drag drift. | Boolean | false |
| resetOnDisable | Reset on Disable. Whether to clear the element's style attributes (e.g., reset position) when enabled becomes false. | Boolean | false |
| uid | Event ID. Used to distinguish different event listeners. Recommended to pass a unique ID in complex scenarios. | String | — |
Typical Cases
Here are typical use cases for the v-tui-drag directive in the TechUI component library.
Dialog Component (Dialog)
This is the most classic usage scenario. Usually, we want:
- The user can only drag by holding the Title Bar (
.dialog-header). - Clicking the Close Button (
.dialog-close) does not trigger dragging. - Dragging is disabled in Fullscreen mode (
fullscreen). - Restrict the dialog from being dragged out of the visible area.
<template>
<div
class="dialog-inner"
v-tui-drag="{
enabled: draggable && !fullscreen, // Disable when fullscreen or configured as not draggable
trigger: '.dialog-header', // Only the title bar is draggable
exclude: '.dialog-close', // Exclude the close button to prevent accidental triggering
containment: true, // Restrict within the parent container
positionType: 'absolute', // Use absolute positioning mode (matches dialog CSS)
inAdpt: isInsideAdaptiveBox, // Enable correction if inside a scaling container
uid: uniqueId
}"
>
<div class="dialog-header">
<span>Title</span>
<button class="dialog-close">X</button>
</div>
<div class="dialog-content">...</div>
</div>
</template>Global Adaptive Container (Adaptive Container)
In data dashboard or editor scenarios, you may need to drag the entire canvas.
- Use
positionType: 'transform'here to get the best rendering performance. - Enable
resetOnDisable: trueto automatically reset the position when the canvas is locked.
<template>
<div
id="tuiAdptOuter"
v-tui-drag="{
enabled: state.dragable, // Controlled by state whether it is draggable
trigger: '#tuiAdpt', // The entire area serves as the handle
resetOnDisable: true, // Reset transform position when disabled
containment: false, // No boundary restriction, allow dragging out of view
positionType: 'transform', // Use GPU acceleration for movement
inAdpt: false, // It is the adaptive layer itself, no need for correction
uid: 'adpt-drag-001'
}"
>
</div>
</template>Technical Details
Coordinate Calculation Logic
The directive implements complex coordinate calculation internally via drag.js:
- Get Start Position (
getStartPosition):
- Transform Mode: Parses
window.getComputedStyle(el).transformmatrix (DOMMatrix) to get the current translate X/Y. - Position Mode: Calculates the offset of
el.getBoundingClientRect()relative tooffsetParent.
- Movement Delta: Calculates
e.clientX - mouseStartX. IfinAdptis enabled, the delta is divided by the global scale factors (scaleX,scaleY) to ensure the mouse stays synchronized with the element in a scaled page. - Boundary Collision (
containCalcTrans/containCalcPos): Pre-calculates the minimum and maximum allowed X/Y values and performs numerical clamping (Clamp) duringmousemove.