VUE带ID拖动组件实现
VUE源码
index.js
<template>
<div
:style="style"
:class="[
{
[classNameActive]: enabled,
[classNameDragging]: dragging,
[classNameResizing]: resizing,
[classNameDraggable]: draggable,
[classNameResizable]: resizable
},
className,
commonClassName
]"
@mousedown="elementDown"
@touchstart="elementTouchDown"
>
<div
v-for="actualHandle in actualHandles"
:key="actualHandle"
:class="[classNameHandle, classNameHandle + '-' + actualHandle]"
:style="{ display: enabled ? 'block' : 'none' }"
@mousedown.stop.prevent="handleDown(actualHandle, $event)"
@touchstart.stop.prevent="handleTouchDown(actualHandle, $event)"
>
<slot :name="actualHandle"></slot>
</div>
<slot></slot>
</div>
</template>
<script>
import {
matchesSelectorToParentElements,
addEvent,
removeEvent
} from './utils/dom'
const events = {
mouse: {
start: 'mousedown',
move: 'mousemove',
stop: 'mouseup'
},
touch: {
start: 'touchstart',
move: 'touchmove',
stop: 'touchend'
}
}
const userSelectNone = {
userSelect: 'none',
MozUserSelect: 'none',
WebkitUserSelect: 'none',
MsUserSelect: 'none'
}
const userSelectAuto = {
userSelect: 'auto',
MozUserSelect: 'auto',
WebkitUserSelect: 'auto',
MsUserSelect: 'auto'
}
let eventsFor = events.mouse
export default {
replace: true,
name: 'VueDraggableResizable',
props: {
className: {
type: String,
default: 'vdr'
},
commonClassName: {
type: String,
default: ''
},
classNameDraggable: {
type: String,
default: 'draggable'
},
classNameResizable: {
type: String,
default: 'resizable'
},
customId: {
// 自定义id,用于区分不同的实例
type: [String, Number],
default: ''
},
classNameDragging: {
type: String,
default: 'dragging'
},
classNameResizing: {
type: String,
default: 'resizing'
},
classNameActive: {
type: String,
default: 'active'
},
classNameHandle: {
type: String,
default: 'handle'
},
disableUserSelect: {
type: Boolean,
default: true
},
enableNativeDrag: {
type: Boolean,
default: false
},
preventDeactivation: {
type: Boolean,
default: false
},
active: {
type: Boolean,
default: false
},
draggable: {
type: Boolean,
default: true
},
resizable: {
type: Boolean,
default: true
},
lockAspectRatio: {
type: Boolean,
default: false
},
w: {
type: Number,
default: 200,
validator: val => val > 0
},
h: {
type: Number,
default: 200,
validator: val => val > 0
},
minWidth: {
type: Number,
default: 0,
validator: val => val >= 0
},
minHeight: {
type: Number,
default: 0,
validator: val => val >= 0
},
maxWidth: {
type: Number,
default: null,
validator: val => val >= 0
},
maxHeight: {
type: Number,
default: null,
validator: val => val >= 0
},
x: {
type: Number,
default: 0,
validator: val => typeof val === 'number'
},
y: {
type: Number,
default: 0,
validator: val => typeof val === 'number'
},
z: {
type: [String, Number],
default: 'auto',
validator: val =>
typeof val === 'string' ? val === 'auto' : val >= 0
},
handles: {
type: Array,
default: () => ['tl', 'tm', 'tr', 'mr', 'br', 'bm', 'bl', 'ml'],
validator: val => {
const s = new Set([
'tl',
'tm',
'tr',
'mr',
'br',
'bm',
'bl',
'ml'
])
return new Set(val.filter(h => s.has(h))).size === val.length
}
},
dragHandle: {
type: String,
default: null
},
dragCancel: {
type: String,
default: null
},
axis: {
type: String,
default: 'both',
validator: val => ['x', 'y', 'both'].includes(val)
},
grid: {
type: Array,
default: () => [1, 1]
},
parent: {
type: Boolean,
default: false
},
onDragStart: {
type: Function,
default: null
},
onResizeStart: {
type: Function,
default: null
},
parentW: {
type: Number,
default: 0,
validator: function (val) {
return val >= 0
}
},
parentH: {
type: Number,
default: 0,
validator: function (val) {
return val >= 0
}
}
},
data: function () {
return {
rawWidth: this.w,
rawHeight: this.h,
rawLeft: this.x,
rawTop: this.y,
rawRight: null,
rawBottom: null,
left: this.x,
top: this.y,
right: null,
bottom: null,
aspectFactor: this.w / this.h,
parentWidth: null,
parentHeight: null,
minW: this.minWidth,
minH: this.minHeight,
maxW: this.maxWidth,
maxH: this.maxHeight,
handle: null,
enabled: this.active,
resizing: false,
dragging: false,
zIndex: this.z
}
},
computed: {
style () {
// console.log(this.left)
return {
position: 'absolute',
top: this.top + 'px',
left: this.left + 'px',
width: this.width + 'px',
height: this.height + 'px',
zIndex: this.zIndex,
...(this.dragging && this.disableUserSelect
? userSelectNone
: userSelectAuto)
}
},
actualHandles () {
if (!this.resizable) return []
return this.handles
},
width () {
return this.parentWidth - this.left - this.right
},
height () {
return this.parentHeight - this.top - this.bottom
},
resizingOnX () {
return (
Boolean(this.handle) &&
(this.handle.includes('l') || this.handle.includes('r'))
)
},
resizingOnY () {
return (
Boolean(this.handle) &&
(this.handle.includes('t') || this.handle.includes('b'))
)
},
isCornerHandle () {
return (
Boolean(this.handle) &&
['tl', 'tr', 'br', 'bl'].includes(this.handle)
)
}
},
watch: {
active (val) {
this.enabled = val
if (val) {
this.$emit('activated', this.customId)
} else {
this.$emit('deactivated')
}
},
z (val) {
if (val >= 0 || val === 'auto') {
this.zIndex = val
}
},
rawLeft (newLeft) {
// console.log('newLeft' + newLeft)
const bounds = this.bounds
const aspectFactor = this.aspectFactor
const lockAspectRatio = this.lockAspectRatio
const left = this.left
const top = this.top
if (bounds.minLeft !== null && newLeft < bounds.minLeft) {
newLeft = bounds.minLeft
} else if (bounds.maxLeft !== null && bounds.maxLeft < newLeft) {
newLeft = bounds.maxLeft
}
if (lockAspectRatio && this.resizingOnX) {
this.rawTop = top - (left - newLeft) / aspectFactor
}
this.left = newLeft
},
rawRight (newRight) {
const bounds = this.bounds
const aspectFactor = this.aspectFactor
const lockAspectRatio = this.lockAspectRatio
const right = this.right
const bottom = this.bottom
if (bounds.minRight !== null && newRight < bounds.minRight) {
newRight = bounds.minRight
} else if (bounds.maxRight !== null && bounds.maxRight < newRight) {
newRight = bounds.maxRight
}
if (lockAspectRatio && this.resizingOnX) {
this.rawBottom = bottom - (right - newRight) / aspectFactor
}
this.right = newRight
},
rawTop (newTop) {
const bounds = this.bounds
const aspectFactor = this.aspectFactor
const lockAspectRatio = this.lockAspectRatio
const left = this.left
const top = this.top
if (bounds.minTop !== null && newTop < bounds.minTop) {
newTop = bounds.minTop
} else if (bounds.maxTop !== null && bounds.maxTop < newTop) {
newTop = bounds.maxTop
}
if (lockAspectRatio && this.resizingOnY) {
this.rawLeft = left - (top - newTop) * aspectFactor
}
this.top = newTop
},
rawBottom (newBottom) {
const bounds = this.bounds
const aspectFactor = this.aspectFactor
const lockAspectRatio = this.lockAspectRatio
const right = this.right
const bottom = this.bottom
if (bounds.minBottom !== null && newBottom < bounds.minBottom) {
newBottom = bounds.minBottom
} else if (
bounds.maxBottom !== null &&
bounds.maxBottom < newBottom
) {
newBottom = bounds.maxBottom
}
if (lockAspectRatio && this.resizingOnY) {
this.rawRight = right - (bottom - newBottom) * aspectFactor
}
this.bottom = newBottom
},
x () {
if (this.resizing || this.dragging) {
return
}
if (this.parent) {
this.bounds = this.calcDragLimits()
}
const delta = this.x - this.left
if (delta % this.grid[0] === 0) {
this.rawLeft = this.x
this.rawRight = this.right - delta
}
},
y () {
if (this.resizing || this.dragging) {
return
}
if (this.parent) {
this.bounds = this.calcDragLimits()
}
const delta = this.y - this.top
if (delta % this.grid[1] === 0) {
this.rawTop = this.y
this.rawBottom = this.bottom - delta
}
},
lockAspectRatio (val) {
if (val) {
this.aspectFactor = this.width / this.height
} else {
this.aspectFactor = undefined
}
},
minWidth (val) {
if (val > 0 && val <= this.width) {
this.minW = val
}
},
minHeight (val) {
if (val > 0 && val <= this.height) {
this.minH = val
}
},
maxWidth (val) {
this.maxW = val
},
maxHeight (val) {
this.maxH = val
},
w () {
if (this.resizing || this.dragging) {
return
}
if (this.parent) {
this.bounds = this.calcResizeLimits()
}
const delta = this.width - this.w
if (delta % this.grid[0] === 0) {
this.rawRight = this.right + delta
}
},
h () {
if (this.resizing || this.dragging) {
return
}
if (this.parent) {
this.bounds = this.calcResizeLimits()
}
const delta = this.height - this.h
if (delta % this.grid[1] === 0) {
this.rawBottom = this.bottom + delta
}
},
parentW (val) {
this.right = val - this.width - this.left
this.parentWidth = val
},
parentH (val) {
this.bottom = val - this.height - this.top
this.parentHeight = val
}
},
created: function () {
// eslint-disable-next-line
if (this.maxWidth && this.minWidth > this.maxWidth)
console.warn(
'[Vdr warn]: Invalid prop: minWidth cannot be greater than maxWidth'
)
// eslint-disable-next-line
if (this.maxWidth && this.minHeight > this.maxHeight)
console.warn(
'[Vdr warn]: Invalid prop: minHeight cannot be greater than maxHeight'
)
this.resetBoundsAndMouseState()
},
mounted: function () {
this.parentElement = this.$el.parentNode
this.parentWidth = this.parentW ? this.parentW : this.parentElement.clientWidth
this.parentHeight = this.parentH ? this.parentH : this.parentElement.clientHeight
if (!this.enableNativeDrag) {
this.$el.ondragstart = () => false
}
[this.parentWidth, this.parentHeight] = this.getParentSize()
this.rawRight = this.parentWidth - this.rawWidth - this.rawLeft
this.rawBottom = this.parentHeight - this.rawHeight - this.rawTop
addEvent(document.documentElement, 'mousedown', this.deselect)
addEvent(
document.documentElement,
'touchend touchcancel',
this.deselect
)
addEvent(window, 'resize', this.checkParentSize)
},
beforeDestroy: function () {
removeEvent(document.documentElement, 'mousedown', this.deselect)
removeEvent(document.documentElement, 'touchstart', this.handleUp)
removeEvent(document.documentElement, 'mousemove', this.move)
removeEvent(document.documentElement, 'touchmove', this.move)
removeEvent(document.documentElement, 'mouseup', this.handleUp)
removeEvent(
document.documentElement,
'touchend touchcancel',
this.deselect
)
removeEvent(window, 'resize', this.checkParentSize)
},
methods: {
/**
* 手动设置位置
* @param left 左边距
* @param top 又边距
*/
setPosByHands (left, top) {
let _self = this
setTimeout(() => {
_self.left = left
_self.rawLeft = left
}, 2000)
// console.log(this.style)
},
resetBoundsAndMouseState () {
this.mouseClickPosition = {
mouseX: 0,
mouseY: 0,
x: 0,
y: 0,
w: 0,
h: 0
}
this.bounds = {
minLeft: null,
maxLeft: null,
minRight: null,
maxRight: null,
minTop: null,
maxTop: null,
minBottom: null,
maxBottom: null
}
},
checkParentSize () {
if (this.parent) {
const [newParentWidth, newParentHeight] = this.getParentSize()
const deltaX = this.parentWidth - newParentWidth
const deltaY = this.parentHeight - newParentHeight
this.rawRight -= deltaX
this.rawBottom -= deltaY
this.parentWidth = newParentWidth
this.parentHeight = newParentHeight
}
},
getParentSize () {
if (this.parent) {
const style = window.getComputedStyle(
this.$el.parentNode,
null
)
return [
parseInt(style.getPropertyValue('width'), 10),
parseInt(style.getPropertyValue('height'), 10)
]
}
return [null, null]
},
elementTouchDown (e) {
eventsFor = events.touch
this.elementDown(e)
},
elementDown (e) {
// 没有e则是外部调用方式
const target = e ? e.target || e.srcElement : ''
const classNameArr = target.className
? target.className.split(' ')
: []
// 被点击元素是关闭按钮
if (classNameArr.includes('close')) {
return
}
if (e && this.$el.contains(target)) {
if (this.onDragStart && this.onDragStart(e) === false) {
return
}
if (
(this.dragHandle &&
!matchesSelectorToParentElements(
target,
this.dragHandle,
this.$el
)) ||
(this.dragCancel &&
matchesSelectorToParentElements(
target,
this.dragCancel,
this.$el
))
) {
return
}
if (!this.enabled) {
this.enabled = true
this.$emit('activated', this.customId)
this.$emit('update:active', true)
}
if (this.draggable) {
this.dragging = true
}
this.mouseClickPosition.mouseX = e.touches
? e.touches[0].pageX
: e.pageX
this.mouseClickPosition.mouseY = e.touches
? e.touches[0].pageY
: e.pageY
this.mouseClickPosition.left = this.left
this.mouseClickPosition.right = this.right
this.mouseClickPosition.top = this.top
this.mouseClickPosition.bottom = this.bottom
if (this.parent) {
this.bounds = this.calcDragLimits()
}
addEvent(document.documentElement, eventsFor.move, this.move)
addEvent(
document.documentElement,
eventsFor.stop,
this.handleUp
)
} else {
// 用于父组件直接调用
if (!this.enabled) {
// console.log(666)
this.enabled = true
this.$emit('activated', this.customId)
this.$emit('update:active', true)
if (this.draggable) {
this.dragging = true
}
}
}
},
calcDragLimits () {
return {
minLeft: (this.parentWidth + this.left) % this.grid[0],
maxLeft:
Math.floor(
(this.parentWidth - this.width - this.left) /
this.grid[0]
) *
this.grid[0] +
this.left,
minRight: (this.parentWidth + this.right) % this.grid[0],
maxRight:
Math.floor(
(this.parentWidth - this.width - this.right) /
this.grid[0]
) *
this.grid[0] +
this.right,
minTop: (this.parentHeight + this.top) % this.grid[1],
maxTop:
Math.floor(
(this.parentHeight - this.height - this.top) /
this.grid[1]
) *
this.grid[1] +
this.top,
minBottom: (this.parentHeight + this.bottom) % this.grid[1],
maxBottom:
Math.floor(
(this.parentHeight - this.height - this.bottom) /
this.grid[1]
) *
this.grid[1] +
this.bottom
}
},
deselect (e) {
const target = e.target || e.srcElement
const regex = new RegExp(this.className + '-([trmbl]{2})', '')
if (!this.$el.contains(target) && !regex.test(target.className)) {
if (this.enabled && !this.preventDeactivation) {
this.enabled = false
this.$emit('deactivated')
this.$emit('update:active', false)
}
removeEvent(document.documentElement, eventsFor.move, this.handleResize)
}
this.resetBoundsAndMouseState()
},
handleTouchDown (handle, e) {
eventsFor = events.touch
this.handleDown(handle, e)
},
handleDown (handle, e) {
if (this.onResizeStart && this.onResizeStart(handle, e) === false) {
return
}
if (e.stopPropagation) e.stopPropagation()
// Here we avoid a dangerous recursion by faking
// corner handles as middle handles
if (this.lockAspectRatio && !handle.includes('m')) {
this.handle = 'm' + handle.substring(1)
} else {
this.handle = handle
}
this.resizing = true
this.mouseClickPosition.mouseX = e.touches
? e.touches[0].pageX
: e.pageX
this.mouseClickPosition.mouseY = e.touches
? e.touches[0].pageY
: e.pageY
this.mouseClickPosition.left = this.left
this.mouseClickPosition.right = this.right
this.mouseClickPosition.top = this.top
this.mouseClickPosition.bottom = this.bottom
this.bounds = this.calcResizeLimits()
addEvent(document.documentElement, eventsFor.move, this.handleMove)
addEvent(document.documentElement, eventsFor.stop, this.handleUp)
},
calcResizeLimits () {
let minW = this.minW
let minH = this.minH
let maxW = this.maxW
let maxH = this.maxH
const aspectFactor = this.aspectFactor
const [gridX, gridY] = this.grid
const width = this.width
const height = this.height
const left = this.left
const top = this.top
const right = this.right
const bottom = this.bottom
if (this.lockAspectRatio) {
if (minW / minH > aspectFactor) {
minH = minW / aspectFactor
} else {
minW = aspectFactor * minH
}
if (maxW && maxH) {
maxW = Math.min(maxW, aspectFactor * maxH)
maxH = Math.min(maxH, maxW / aspectFactor)
} else if (maxW) {
maxH = maxW / aspectFactor
} else if (maxH) {
maxW = aspectFactor * maxH
}
}
maxW = maxW - (maxW % gridX)
maxH = maxH - (maxH % gridY)
const limits = {
minLeft: null,
maxLeft: null,
minTop: null,
maxTop: null,
minRight: null,
maxRight: null,
minBottom: null,
maxBottom: null
}
if (this.parent) {
limits.minLeft = (this.parentWidth + left) % gridX
limits.maxLeft =
left + Math.floor((width - minW) / gridX) * gridX
limits.minTop = (this.parentHeight + top) % gridY
limits.maxTop =
top + Math.floor((height - minH) / gridY) * gridY
limits.minRight = (this.parentWidth + right) % gridX
limits.maxRight =
right + Math.floor((width - minW) / gridX) * gridX
limits.minBottom = (this.parentHeight + bottom) % gridY
limits.maxBottom =
bottom + Math.floor((height - minH) / gridY) * gridY
if (maxW) {
limits.minLeft = Math.max(
limits.minLeft,
this.parentWidth - right - maxW
)
limits.minRight = Math.max(
limits.minRight,
this.parentWidth - left - maxW
)
}
if (maxH) {
limits.minTop = Math.max(
limits.minTop,
this.parentHeight - bottom - maxH
)
limits.minBottom = Math.max(
limits.minBottom,
this.parentHeight - top - maxH
)
}
if (this.lockAspectRatio) {
limits.minLeft = Math.max(
limits.minLeft,
left - top * aspectFactor
)
limits.minTop = Math.max(
limits.minTop,
top - left / aspectFactor
)
limits.minRight = Math.max(
limits.minRight,
right - bottom * aspectFactor
)
limits.minBottom = Math.max(
limits.minBottom,
bottom - right / aspectFactor
)
}
} else {
limits.minLeft = null
limits.maxLeft =
left + Math.floor((width - minW) / gridX) * gridX
limits.minTop = null
limits.maxTop =
top + Math.floor((height - minH) / gridY) * gridY
limits.minRight = null
limits.maxRight =
right + Math.floor((width - minW) / gridX) * gridX
limits.minBottom = null
limits.maxBottom =
bottom + Math.floor((height - minH) / gridY) * gridY
if (maxW) {
limits.minLeft = -(right + maxW)
limits.minRight = -(left + maxW)
}
if (maxH) {
limits.minTop = -(bottom + maxH)
limits.minBottom = -(top + maxH)
}
if (this.lockAspectRatio && (maxW && maxH)) {
limits.minLeft = Math.min(limits.minLeft, -(right + maxW))
limits.minTop = Math.min(limits.minTop, -(maxH + bottom))
limits.minRight = Math.min(limits.minRight, -left - maxW)
limits.minBottom = Math.min(limits.minBottom, -top - maxH)
}
}
return limits
},
move (e) {
if (this.resizing) {
this.handleMove(e)
} else if (this.dragging) {
this.elementMove(e)
}
},
elementMove (e) {
const axis = this.axis
// const grid = this.grid
const mouseClickPosition = this.mouseClickPosition
const tmpDeltaX =
axis && axis !== 'y'
? mouseClickPosition.mouseX -
(e.touches ? e.touches[0].pageX : e.pageX)
: 0
const tmpDeltaY =
axis && axis !== 'x'
? mouseClickPosition.mouseY -
(e.touches ? e.touches[0].pageY : e.pageY)
: 0
const [deltaX, deltaY] = this.snapToGrid(
this.grid,
tmpDeltaX,
tmpDeltaY
)
this.rawTop = mouseClickPosition.top - deltaY
this.rawBottom = mouseClickPosition.bottom + deltaY
this.rawLeft = mouseClickPosition.left - deltaX
this.rawRight = mouseClickPosition.right + deltaX
// console.log(this.left, this.top)
// console.log(this.rawLeft, this.rawTop)
this.$emit('dragging', this.left, this.top)
},
handleMove (e) {
const handle = this.handle
const mouseClickPosition = this.mouseClickPosition
const tmpDeltaX =
mouseClickPosition.mouseX -
(e.touches ? e.touches[0].pageX : e.pageX)
const tmpDeltaY =
mouseClickPosition.mouseY -
(e.touches ? e.touches[0].pageY : e.pageY)
const [deltaX, deltaY] = this.snapToGrid(
this.grid,
tmpDeltaX,
tmpDeltaY
)
if (handle.includes('b')) {
this.rawBottom = mouseClickPosition.bottom + deltaY
} else if (handle.includes('t')) {
this.rawTop = mouseClickPosition.top - deltaY
}
if (handle.includes('r')) {
this.rawRight = mouseClickPosition.right + deltaX
} else if (handle.includes('l')) {
this.rawLeft = mouseClickPosition.left - deltaX
}
this.$emit(
'resizing',
this.left,
this.top,
this.width,
this.height
)
},
handleUp (e) {
this.handle = null
this.resetBoundsAndMouseState()
this.rawTop = this.top
this.rawBottom = this.bottom
this.rawLeft = this.left
this.rawRight = this.right
if (this.resizing) {
this.resizing = false
this.$emit(
'resizestop',
this.left,
this.top,
this.width,
this.height,
this.customId
)
}
if (this.dragging) {
this.dragging = false
this.$emit('dragstop', this.left, this.top, this.customId)
}
removeEvent(
document.documentElement,
eventsFor.move,
this.handleMove
)
},
snapToGrid (grid, pendingX, pendingY) {
const x = Math.round(pendingX / grid[0]) * grid[0]
const y = Math.round(pendingY / grid[1]) * grid[1]
return [x, y]
}
}
}
</script>
JS源码
utils/dom.js
import { isFunction } from './fns'
export function matchesSelectorToParentElements (el, selector, baseNode) {
let node = el
const matchesSelectorFunc = [
'matches',
'webkitMatchesSelector',
'mozMatchesSelector',
'msMatchesSelector',
'oMatchesSelector'
].find(func => isFunction(node[func]))
if (!isFunction(node[matchesSelectorFunc])) return false
do {
if (node[matchesSelectorFunc](selector)) return true
if (node === baseNode) return false
node = node.parentNode
} while (node)
return false
}
export function addEvent (el, event, handler) {
if (!el) {
return
}
if (el.attachEvent) {
el.attachEvent('on' + event, handler)
} else if (el.addEventListener) {
el.addEventListener(event, handler, true)
} else {
el['on' + event] = handler
}
}
export function removeEvent (el, event, handler) {
if (!el) {
return
}
if (el.detachEvent) {
el.detachEvent('on' + event, handler)
} else if (el.removeEventListener) {
el.removeEventListener(event, handler, true)
} else {
el['on' + event] = null
}
}
utils/fns.js
export function isFunction (func) {
return (typeof func === 'function' || Object.prototype.toString.call(func) === '[object Function]')
}
CSS源码
.vdr {
touch-action: none;
position: absolute;
box-sizing: border-box;
}
.handle {
box-sizing: border-box;
position: absolute;
width: 10px;
height: 10px;
background: #EEE;
border: 1px solid #333;
}
.handle-tl {
top: -10px;
left: -10px;
cursor: nw-resize;
}
.handle-tm {
top: -10px;
left: 50%;
margin-left: -5px;
cursor: n-resize;
}
.handle-tr {
top: -10px;
right: -10px;
cursor: ne-resize;
}
.handle-ml {
top: 50%;
margin-top: -5px;
left: -10px;
cursor: w-resize;
}
.handle-mr {
top: 50%;
margin-top: -5px;
right: -10px;
cursor: e-resize;
}
.handle-bl {
bottom: -10px;
left: -10px;
cursor: sw-resize;
}
.handle-bm {
bottom: -10px;
left: 50%;
margin-left: -5px;
cursor: s-resize;
}
.handle-br {
bottom: -10px;
right: -10px;
cursor: se-resize;
}
@media only screen and (max-width: 768px) {
[class*="handle-"]:before {
content: '';
left: -10px;
right: -10px;
bottom: -10px;
top: -10px;
position: absolute;
}
}
使用方式VUE
<vue-draggable-resizable
v-for="(device, index) in deviceList"
:key="index"
:custom-id="device.id"
:w="device.width"
:h="device.height"
:x="device.left"
:y="device.top"
:min-width="30"
:min-height="30"
:lock-aspect-ratio="true"
:active="device.active"
:parent="true"
:parentW="Number(rorm.width)"
:parentH="Number(form.height)"
@resizestop="handleResizeStop"
@dragstop="handleDragStop"
@activated="dragResizeClick(device.key, device.id)"
@deactivated="cancelSelect()"
class="device-drag-resize"
></vue-draggable-resizable>
使用方式JS
缩放结束调用
/**
* 组件缩放结束后重新赋值
* @param left 左边距
* @param top 上边距
* @param width 宽度
* @param height 高度
* @param customId 组件id
*/
handleResizeStop (left, top, width, height, customId) {
console.info(111)
}
拖动结束调用
/**
* 组件拖拽结束后重新赋值
* @param left 左边距
* @param top 上边距
* @param customId 组件id
*/
handleDragStop (left, top, customId) {
console.info(111)
},
点击事件调用
/**
* 点击事件调用
*
* @param id 拖动的组件id
*/
dragResizeClick (key, id) {
console.info(1111)
}
点击组件外部调用
/**
* 点击组件外部调用
*/
cancelSelect () {
console.info(1111)
},