vue項目中彈窗拖拽、縮放功能實現(xiàn)過程
更新時間:2025年10月25日 09:25:53 作者:Qredsun
文章介紹了如何在項目中實現(xiàn)會話窗口的拖拽和縮放功能,包括指定拖拽的窗口和區(qū)域、縮放的對象和區(qū)域,以及如何添加指定區(qū)域和改變鼠標樣式
背景
在項目中有一個會話窗口,需要支持用戶拖拽、縮放的功能
實現(xiàn)
拖拽
指定要拖拽的窗口
// 拖拽 <div ref="resizableBox" ><div class="header"></div></div>
const visible = ref(false)
const position = ref({ x: 200, y: 100 })
const emit = defineEmits(['update:visible', 'closeDialog'])
let dragging = false
let offsetX, offsetY, maxLeft, maxTop
const startDrag = (e) => {
dragging = true
offsetX = e.clientX - position.value.x
offsetY = e.clientY - position.value.y
document.body.style.userSelect = 'none'; // 防止選中文本
document.addEventListener('mousemove', onDrag)
document.addEventListener('mouseup', stopDrag)
}
const onDrag = (e) => {
if (!dragging) return
position.value.x = Math.max(0, Math.min(maxLeft,(e.clientX - offsetX)))
position.value.y = Math.max(0, Math.min(maxTop,(e.clientY - offsetY)))
console.log(maxLeft,position.value.x,maxTop,position.value.y)
}
const stopDrag = () => {
dragging = false
document.removeEventListener('mousemove', onDrag)
document.removeEventListener('mouseup', stopDrag)
}
const initDialogPosition = () => {
// 初始居中:等待 DOM 渲染后計算中心點
nextTick(() => {
const dialog = document.querySelector('.header')
if (dialog) {
const { innerWidth, innerHeight } = window
const { offsetWidth, offsetHeight } = dialog as HTMLElement
maxLeft = innerWidth - offsetWidth
maxTop = innerHeight - Math.max(560, offsetHeight)
position.value.x = maxLeft / 2
position.value.y = maxTop / 3
console.log('innerWidth', innerWidth, innerHeight)
console.log('dialog', dialog.getBoundingClientRect())
}
})
}
指定拖拽的區(qū)域
const initDialogPosition = () => {
// 初始居中:等待 DOM 渲染后計算中心點
nextTick(() => {
const dialog = document.querySelector('.header')
if (dialog) {
const { innerWidth, innerHeight } = window
const { offsetWidth, offsetHeight } = dialog as HTMLElement
maxLeft = innerWidth - offsetWidth
maxTop = innerHeight - Math.max(560, offsetHeight)
position.value.x = maxLeft / 2
position.value.y = maxTop / 3
console.log('innerWidth', innerWidth, innerHeight)
console.log('dialog', dialog.getBoundingClientRect())
}
})
}
縮放
指定縮放的對象
// 縮放 <div ref="resizableBox" ><div class="resizer" @mousedown="initResize"></div></div>
const resizableBox = ref<HTMLElement | null>(null);
function initResize(e: MouseEvent) {
const box = resizableBox.value;
if (!box) return;
const startX = e.clientX;
const startY = e.clientY;
const startWidth = box.offsetWidth;
const startHeight = box.offsetHeight;
function onMouseMove(event: MouseEvent) {
const newWidth = Math.max(400, startWidth + (event.clientX - startX));
const newHeight = Math.max(560, startHeight + (event.clientY - startY));
box.style.width = `${newWidth}px`;
box.style.height = `${newHeight}px`;
}
function onMouseUp() {
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
}
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
}
也可以添加指定區(qū)域,實現(xiàn)鼠標樣式轉變
.resizer {
width: 14px;
height: 14px;
position: absolute;
right: 0;
bottom: 0;
cursor: se-resize;
z-index: 10;
border-radius: 2px;
}
總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
vueJs實現(xiàn)DOM加載完之后自動下拉到底部的實例代碼
這篇文章主要介紹了vueJs實現(xiàn)DOM加載完成之后自動下拉到底部的實例代碼,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-08-08
關于vuex狀態(tài)刷新網(wǎng)頁時數(shù)據(jù)被清空問題及解決
這篇文章主要介紹了關于vuex狀態(tài)刷新網(wǎng)頁時數(shù)據(jù)被清空問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07
vue echarts實現(xiàn)柱狀圖動態(tài)展示
這篇文章主要為大家詳細介紹了vue echarts實現(xiàn)柱狀圖動態(tài)展示,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-09-09
vue結合axios實現(xiàn)restful風格的四種請求方式
這篇文章主要介紹了vue結合axios實現(xiàn)restful風格的四種請求方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06
vue 實現(xiàn)通過手機發(fā)送短信驗證碼注冊功能
這篇文章主要介紹了vue 實現(xiàn)通過手機發(fā)送短信驗證碼注冊功能的相關資料,需要的朋友可以參考下2018-04-04

