|
@@ -1,3 +1,4 @@
|
|
|
+
|
|
|
//拖动对话框
|
|
|
export default {
|
|
|
bind(el, binding, vnode) {
|
|
@@ -8,61 +9,88 @@ export default {
|
|
|
let dragStart = { x: 0, y: 0 }
|
|
|
let dialogStart = { top: 0, left: 0 }
|
|
|
|
|
|
- //向对话框注册鼠标按下事件
|
|
|
+ // 对话框居中
|
|
|
+ const centerDialog = () => {
|
|
|
+ // 等待DOM更新完成
|
|
|
+ setTimeout(() => {
|
|
|
+ const dialogRect = dialogEl.getBoundingClientRect()
|
|
|
+ const centerX = (window.innerWidth - dialogRect.width) / 2
|
|
|
+ const centerY = (window.innerHeight - dialogRect.height) / 2
|
|
|
+
|
|
|
+ // 应用居中样式
|
|
|
+ dialogEl.style.cssText += `
|
|
|
+ top: ${centerY}px;
|
|
|
+ left: ${centerX}px;
|
|
|
+ transform: none; // 清除element默认transform
|
|
|
+ `
|
|
|
+ // 更新初始位置记录
|
|
|
+ dialogStart.top = centerY
|
|
|
+ dialogStart.left = centerX
|
|
|
+ }, 50) // 适当延迟确保元素渲染
|
|
|
+ }
|
|
|
+
|
|
|
+ // 监听对话框打开事件
|
|
|
+ const dialogComponent = vnode.componentInstance
|
|
|
+ if (dialogComponent) {
|
|
|
+ dialogComponent.$watch('visible', (newVal) => {
|
|
|
+ if (newVal) {
|
|
|
+ centerDialog() // 每次打开都居中
|
|
|
+ // 添加窗口resize监听
|
|
|
+ window.addEventListener('resize', centerDialog)
|
|
|
+ } else {
|
|
|
+ // 关闭时移除resize监听
|
|
|
+ window.removeEventListener('resize', centerDialog)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ //监听鼠标左键按下事件
|
|
|
headerEl.addEventListener('mousedown', (event) => {
|
|
|
- if (event.button === 0) {//按下的是左键
|
|
|
+ if (event.button === 0) {
|
|
|
dragging = true;
|
|
|
dragStart.x = event.clientX
|
|
|
dragStart.y = event.clientY
|
|
|
const rect = dialogEl.getBoundingClientRect()
|
|
|
- dialogStart.top = rect.top + window.scrollY
|
|
|
- dialogStart.left = rect.left + window.scrollX
|
|
|
- document.body.style.userSelect = 'none'; // 禁止文本选择
|
|
|
+ dialogStart.top = rect.top
|
|
|
+ dialogStart.left = rect.left
|
|
|
+ document.body.style.userSelect = 'none';
|
|
|
}
|
|
|
})
|
|
|
|
|
|
+ //监听鼠标移动事件
|
|
|
document.addEventListener('mousemove', (event) => {
|
|
|
if (dragging) {
|
|
|
- const deltaX = event.clientX - dragStart.x - 400
|
|
|
- const deltaY = event.clientY - dragStart.y - 110
|
|
|
+ const deltaX = event.clientX - dragStart.x
|
|
|
+ const deltaY = event.clientY - dragStart.y
|
|
|
+ // 直接设置新位置,无边界约束
|
|
|
dialogEl.style.top = `${dialogStart.top + deltaY}px`
|
|
|
dialogEl.style.left = `${dialogStart.left + deltaX}px`
|
|
|
}
|
|
|
})
|
|
|
|
|
|
+ //监听鼠标松开事件
|
|
|
document.addEventListener('mouseup', () => {
|
|
|
dragging = false
|
|
|
- document.body.style.userSelect = '' // 恢复文本选择
|
|
|
+ document.body.style.userSelect = ''
|
|
|
})
|
|
|
|
|
|
- // 在组件销毁时移除事件监听器
|
|
|
- el._removeDragListeners = () => {
|
|
|
+ // 组件销毁时的清理
|
|
|
+ const cleanup = () => {
|
|
|
+ window.removeEventListener('resize', centerDialog)
|
|
|
headerEl.removeEventListener('mousedown', startDrag)
|
|
|
document.removeEventListener('mousemove', onDrag)
|
|
|
document.removeEventListener('mouseup', stopDrag)
|
|
|
}
|
|
|
|
|
|
- // 使用 Vue 的 onBeforeUnmount 钩子(或在 Vue 2 中使用 destroyed 钩子)来移除监听器
|
|
|
- //vnode.context.$once('hook:beforeUnmount', el._removeDragListeners);
|
|
|
- // 对于 Vue 2,使用以下代码代替上面的行:
|
|
|
- vnode.context.$on('hook:destroyed', el._removeDragListeners);
|
|
|
-
|
|
|
- // 注意:在 Vue 3 中,由于函数式组件和组合式 API 的引入,
|
|
|
- // 你可能需要使用 `onUnmounted` 或其他方法来确保在组件销毁时清理资源。
|
|
|
-
|
|
|
- function startDrag(event) {
|
|
|
- // 这里的逻辑与上面的 headerEl.addEventListener 中的逻辑相同,
|
|
|
- // 但由于我们将其封装在了一个函数中,所以可以在需要时调用或移除。
|
|
|
- // 然而,在这个例子中,我们直接在事件监听器中使用了内联函数,
|
|
|
- // 因此这个 `startDrag` 函数实际上没有被使用。你可以根据需要选择是否保留它。
|
|
|
+ // Vue2销毁钩子
|
|
|
+ vnode.context.$on('hook:destroyed', cleanup)
|
|
|
+ // Vue3兼容
|
|
|
+ if (vnode.componentInstance && vnode.componentInstance.$options) {
|
|
|
+ vnode.componentInstance.$on('hook:beforeDestroy', cleanup)
|
|
|
}
|
|
|
|
|
|
- function onDrag(event) {
|
|
|
- // 同上,这里的逻辑与 document.addEventListener('mousemove') 中的逻辑相同。
|
|
|
- }
|
|
|
-
|
|
|
- function stopDrag() {
|
|
|
- // 同上,这里的逻辑与 document.addEventListener('mouseup') 中的逻辑相同。
|
|
|
- }
|
|
|
+ // 初始化定位样式
|
|
|
+ dialogEl.style.position = 'fixed'
|
|
|
+ dialogEl.style.margin = '0'
|
|
|
}
|
|
|
}
|