可拖动弹窗

<!-- 通用弹窗 -->
<script setup>
import { Logger } from 'sass'
import { nextTick, onMounted, ref } from 'vue'
const emit = defineEmits(['close']) //
const props = defineProps({
    //标题
    title: {
        type: String,
        default: '标题',
    },
    //弹窗宽度
    width: {
        type: String,
        default: '521px',
    },
    //弹窗书否可拖动
    isDrow: {
        type: Boolean,
        default: false,
    },
})

const boxLeft = ref(0)
const boxTop = ref(0)
const startX = ref(0)
const startY = ref(0)
const currentX = ref(0)
const currentY = ref(0)
const modelref = ref()

const handleClose = () => {
    emit('close')
}
const onmousedown = (e) => {
    if (!props.isDrow) return
    let Dom = modelref.value
    // console.log(Dom.style.left);
    // console.log(Dom.style.top);
    if (Dom.style.left) {
        boxLeft.value = parseInt(Dom.style.left.slice(0, Dom.style.left.length - 2))
    }
    if (Dom.style.top) {
        boxTop.value = parseInt(Dom.style.top.slice(0, Dom.style.left.length - 2))
    }

    startX.value = e.pageX
    startY.value = e.pageY
    // localStorage.setItem('moveModelleft', startX.value);
    // localStorage.setItem('moveModeltop', startY.value);
    Dom.onmousemove = dragMove
}

const dragMove = (e) => {
    let moveX = e.pageX - startX.value
    let moveY = e.pageY - startY.value
    let curL = boxLeft.value + moveX < -20 ? 0 : boxLeft.value + moveX
    let curT = boxTop.value + moveY < -20 ? 0 : boxTop.value + moveY
    let Dom = modelref.value
    // 3. 将盒子的left和top分别设置为它应该出现的值
    Dom.style.left = `${curL}px`
    Dom.style.top = `${curT}px`
    currentX.value = curL
    currentY.value = curT
}

const mouseup = () => {
    if (!props.isDrow) return
    modelref.value.onmousemove = null
    localStorage.setItem('moveModelleft', currentX.value)
    localStorage.setItem('moveModeltop', currentY.value)
    boxLeft.value = 0
    boxTop.value = 0
    startX.value = 0
    startY.value = 0
    currentX.value = 0
    currentY.value = 0
}

onMounted(() => {
    window.addEventListener('click', () => {
        if (modelref.value.onmousemove) {
            mouseup()
        }
    })
    nextTick(() => {
        if (props.isDrow) {
            let Dom = modelref.value
            // 3. 将盒子的left和top分别设置为它应该出现的值
            let left = Number(localStorage.getItem('moveModelleft')) || 400
            let top = Number(localStorage.getItem('moveModeltop')) || 120
            Dom.style.left = left + 'px'
            Dom.style.top = top + 'px'
            currentX.value = left
            currentY.value = top
        }
    })
})
</script>
<template>
    <div class="bigBox" ref="modelref" :style="{ width: props.width }">
        <div class="header" @mousedown="onmousedown" @mouseup="mouseup">
            <div style="padding: 10px 20px 0">{{ props.title }}</div>
            <div style="padding: 10px 20px 0; cursor: pointer">
                <div @click="handleClose">
                    <Icon @click="handleClose" name="el-icon-Close" size="25" color="#fff" />
                </div>
            </div>
        </div>

        <div class="modelBody">
            <slot></slot>
        </div>
        <div class="footer">
            <slot name="footer"></slot>
        </div>
    </div>
</template>
<style lang="scss" scope>
.bigBox {
    background: rgba(11, 37, 65, 0.7);
    border: 1px solid #06f7ff;
    border-radius: 5px;
    z-index: 999;
    position: absolute;
    // right: 10px;
    .header {
        display: flex;
        justify-content: space-between;
        // padding: 10px 20px;
        background-image: linear-gradient(to right, rgba(rgb(0, 174, 255), 0.4), rgba(255, 0, 0, 0));
        border-bottom: 1px solid #06f7ff;
        border-radius: 5px 5px 0px 0px;
    }
    .modelBody {
        padding: 20px;
        max-height: 70vh;
        overflow: auto;
    }
    .footer {
        display: flex;
        justify-content: center;

        margin-bottom: 10px;
    }
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值