使用vue-grid-layout实现从侧边栏拖拽组件到设计器中,drag事件会再过程中执行多次造成卡顿,当松开鼠标后还会等待drag事件执行结束才会显示组件(用dragend控制显示),现在怎么优化这个drag事件,使用节流行不通,delay 设置多少都一样
<div
class="box"
v-for="(item, index) in items.list"
:key="index"
@drag="dragThrottle(item)"
@dragend="dragend(item)"
draggable="true"
unselectable="on"
>
throttle(fn, delay = 100) {
let timer = null
return function () {
if (!timer) {
timer = setTimeout(() => {
fn.apply(this, arguments)
timer = null
}, delay)
}
}
},
dragThrottle(item) {
this.throttle(this.drag(item), 1000)
},
drag(item) {
console.log('drag')
const parentRect = document.getElementById('custom-design').getBoundingClientRect()
const mouseInGrid =
mouseXY.x > parentRect.left &&
mouseXY.x < parentRect.right &&
mouseXY.y > parentRect.top &&
mouseXY.y < parentRect.bottom
if (mouseInGrid && this.layout.findIndex((item) => item.i === 'drop') === -1) {
this.layout.push({
x: (this.layout.length * 2) % (this.colNum || 12),
y: this.layout.length + (this.colNum || 12),
w: item.w,
h: item.h,
i: 'drop',
})
}
const index = this.layout.findIndex((item) => item.i === 'drop')
const indexId = Date.now()
if (index !== -1) {
try {
this.$refs.gridlayout.$children[this.layout.length].$refs.item.style.display = 'none'
} catch {}
const el = this.$refs.gridlayout.$children[index]
el.dragging = { top: mouseXY.y - parentRect.top, left: mouseXY.x - parentRect.left }
const new_pos = el.calcXY(mouseXY.y - parentRect.top, mouseXY.x - parentRect.left)
if (mouseInGrid) {
this.$refs.gridlayout.dragEvent('dragstart', 'drop', new_pos.x, new_pos.y, item.h, item.w)
DragPos.i = indexId
DragPos.x = this.layout[index].x
DragPos.y = this.layout[index].y
DragPos.w = item.w
DragPos.h = item.h
}
if (!mouseInGrid) {
this.$refs.gridlayout.dragEvent('dragend', 'drop', new_pos.x, new_pos.y, item.h, item.w)
this.layout = this.layout.filter((obj) => obj.i !== 'drop')
}
}
},
dragend(item) {
const parentRect = document.getElementById('custom-design').getBoundingClientRect()
const mouseInGrid =
mouseXY.x > parentRect.left &&
mouseXY.x < parentRect.right &&
mouseXY.y > parentRect.top &&
mouseXY.y < parentRect.bottom
if (mouseInGrid) {
this.$refs.gridlayout.dragEvent('dragend', 'drop', DragPos.x, DragPos.y, DragPos.h, DragPos.w)
this.layout = this.layout.filter((obj) => obj.i !== 'drop')
this.layout.push({
x: DragPos.x,
y: DragPos.y,
w: DragPos.w,
h: DragPos.h,
i: DragPos.i,
type: item.type,
widgetConfig: item.widgetConfig,
})
this.$nextTick(() => {
this.$refs.gridlayout.dragEvent('dragend', DragPos.i, DragPos.x, DragPos.y, DragPos.h, DragPos.w)
})
try {
this.$refs.gridLayout.$children[this.layout.length].$refs.item.style.display = 'block'
} catch {}
}
该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
您可以尝试使用requestAnimationFrame
(RAF)来优化drag
事件,以避免在拖动过程中执行太多的计算和渲染。RAF会在下一帧绘制之前执行回调函数,这可以避免在拖动时导致太多的计算和渲染,并提高性能和流畅度。
以下是一个示例代码,展示如何使用requestAnimationFrame
来优化drag
事件:
dragThrottle(item) {
let isDragging = false
let lastTime = 0
let requestID = null
const handleDrag = () => {
const currentTime = Date.now()
if (currentTime - lastTime > 16) { // 限制每秒执行的次数为60
lastTime = currentTime
this.drag(item)
}
if (isDragging) {
requestID = requestAnimationFrame(handleDrag)
} else {
cancelAnimationFrame(requestID)
}
}
const dragStartHandler = () => {
isDragging = true
handleDrag()
}
const dragEndHandler = () => {
isDragging = false
}
this.$el.addEventListener('dragstart', dragStartHandler, false)
this.$el.addEventListener('dragend', dragEndHandler, false)
},
在这个示例代码中,handleDrag
函数使用requestAnimationFrame
来限制每秒执行的次数,防止在拖动期间执行太多的计算和渲染。在dragstart
事件中,启动handleDrag
函数,在dragend
事件中停止它。
您可以将这个示例代码适应您的组件和应用程序,以优化您的drag
事件并提高性能。
如果以上回答对您有所帮助,点击一下采纳该答案~谢谢