由于Vue3文档缺失,示例10也是也跑不起来,这边参考示例改动了一下。
改动的点主要是
this
指向、$children
相关的问题
在Vue3中移除了$children
可以使用$ref
替代
参考文章:计算坐标方法重写、文档示例
关键点:计算中的子组件取值使用ref绑定即可
对于循环的Dom树可以参考模板引用
完整代码:
<template> <div class="user-canvas" @dragenter.prevent @dragover.prevent> <div id="content" class="w-full pb-16"> <grid-layout class="min-h-screen" ref="gridlayout" :layout.sync="gridConfig.layout" :col-num="60" :row-height="30" :vertical-compact="false" :use-css-transforms="true" > <grid-item ref="gridItemRefs" v-for="item in gridConfig.layout" class="h-full select-none relative overflow-hidden" :static="item.static" :x="item.x" :y="item.y" :w="item.w" :h="item.h" :i="item.i" :minW="8" :minH="2" > <div>{{item.key}}</div> </grid-item> </grid-layout> </div> </div> </template>
复制
import { ref, onUnmounted } from 'vue' // ref const gridlayout = ref(null) const gridItemRefs = ref([]) // 计算坐标用 let mouseXY = { x: null, y: null } let DragPos = { x: null, y: null, w: 4, h: 4, i: null } const gridConfig ={layout:[{x: 0,y: 3,w: 4,h: 12,i: '1',static: true,moved: false} ]} const handleDrop = (event) => { event.preventDefault() // TODO } // 开始拖动 const drag = (e) => { let parentRect = document.getElementById('content').getBoundingClientRect() let mouseInGrid = false if ( mouseXY.x > parentRect.left && mouseXY.x < parentRect.right && mouseXY.y > parentRect.top && mouseXY.y < parentRect.bottom ) { mouseInGrid = true } if (mouseInGrid === true && gridConfig.layout.findIndex((item) => item.i === 'drop') === -1) { gridConfig.layout.push({ x: (gridConfig.layout.length * 2) % 12, y: gridConfig.layout.length + 12, // puts it at the bottom w: gridConfig.dragType?.w || 4, h: gridConfig.dragType?.h || 4, i: 'drop' }) } let index = gridConfig.layout.findIndex((item) => item.i === 'drop') if (index !== -1) { try { gridItemRefs.value[gridConfig.layout.length - 1].$refs.item.style.display = 'none' } catch {} let el = gridItemRefs.value[index] // el.dragging = { top: mouseXY.y - parentRect.top, left: mouseXY.x - parentRect.left } let new_pos = calcXY(el, mouseXY.y - parentRect.top, mouseXY.x - parentRect.left, 1, 1) if (mouseInGrid === true) { // 红色游标部分 gridlayout.value.dragEvent( 'dragstart', 'drop', new_pos.x, new_pos.y, gridConfig.dragType?.h || 4, gridConfig.dragType?.w || 4 ) DragPos.i = String(index) DragPos.x = gridConfig.layout[index].x DragPos.y = gridConfig.layout[index].y } if (mouseInGrid === false) { gridlayout.value.dragEvent('dragend', 'drop', new_pos.x, new_pos.y, 1, 1) gridConfig.layout = gridConfig.layout.filter((obj) => obj.i !== 'drop') } } } // 释放拖动 const dragend = (e) => { let parentRect = document.getElementById('content').getBoundingClientRect() let mouseInGrid = false if ( mouseXY.x > parentRect.left && mouseXY.x < parentRect.right && mouseXY.y > parentRect.top && mouseXY.y < parentRect.bottom ) { mouseInGrid = true } if (mouseInGrid === true) { gridlayout.value.dragEvent('dragend', 'drop', DragPos.x, DragPos.y, 1, 1) gridConfig.addGridItem(DragPos) gridConfig.layout = gridConfig.layout.filter((obj) => obj.i !== 'drop') } gridItemRefs.value[gridConfig.layout.length - 1].$refs.item.style.display = 'none' } // 计算坐标 const calcXY = (el, top, left, width, height) => { const colWidth = el.calcColWidth() let x = Math.round((left - 10) / (colWidth + 10)) let y = Math.round((top - 10) / (el.rowHeight + 10)) const _width = width || el.innerW const _height = height || el.innerH x = Math.max(Math.min(x, el.cols - _width), 0) y = Math.max(Math.min(y, el.maxRows - _height), 0) return { x, y } } // 加载完成后监听鼠标事件 onMounted(() => { document.addEventListener( 'dragover', function (e) { mouseXY.x = e.clientX mouseXY.y = e.clientY }, false ) }) // 销毁时关闭监听 onUnmounted(() => { document.removeEventListener( 'dragover', function (e) { mouseXY.x = null mouseXY.y = null }, false ) })
复制