We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
使用 card preset 封装了一下 modal,可拖动,可以省写几个属性。
x-n-modal.vue
<template> <n-modal id="basic-modal" $show="showModal" :style="{ width: modalWidth }" preset="card" :size="size" :bordered="false" :closable="closable" :auto-focus="autoFocus" :block-scroll="blockScroll" :close-on-esc="closeOnEsc" :display-directive="displayDirective" :mask-closable="maskClosable" :to="to" :transform-origin="transformOrigin" :trap-focus="trapFocus" :z-index="zIndex" @close="emit('close')" @after-enter="$emit('after-enter')" @after-leave="$emit('after-leave')" @esc="$emit('esc')" @mask-click="$emit('mask-click')" @update:show="$emit('update:show', $event)"> <template #header> <div id="basic-modal-bar" class="w-full" :class="{'cursor-move': draggable}">{{ title }}</div> </template> <slot name="default" /> <template #action> <slot v-if="showAction" name="action"> <n-space class="!justify-end"> <n-button :size="size" @click="cancelModal">{{ negativeText }}</n-button> <n-button :size="size" type="primary" :loading="subLoading" @click="confirmModal">{{ positiveText }}</n-button> </n-space> </slot> </template> </n-modal> </template> <script setup> const emit = defineEmits(['close', 'positive-click', 'update:show', 'after-leave', 'after-enter', 'mask-click', 'esc', 'negative-click']) const showModal = defineModel('show', { type: Boolean, default: false }) const props = defineProps({ size: { type: String }, title: { type: String, default: '' }, width: { type: [String, Number], default: 500 }, draggable: { type: Boolean, default: false }, showAction: { type: Boolean, default: true }, negativeText: { type: String, default: '取消' }, positiveText: { type: String, default: '确定' }, closable: { type: Boolean, default: true }, autoFocus: { type: Boolean, default: false }, blockScroll: { type: Boolean, default: true }, closeOnEsc: { type: Boolean, default: true }, closeOnConfirm: { type: Boolean, default: true }, // 确认时不自动关闭弹窗 closeOnCancel: { type: Boolean, default: true }, // 取消时不自动关闭弹窗 displayDirective: { type: String, default: 'if' }, // 'if' | 'show' maskClosable: { type: Boolean, default: true }, to: { type: String, default: 'body' }, transformOrigin: { type: String, default: 'mouse' }, // 'mouse' | 'center' trapFocus: { type: Boolean, default: true }, zIndex: { type: Number }, }) const modalWidth = computed(() => { return typeof props.width === 'number' ? `${props.width}px` : props.width }) let subLoading = $ref(false) watch(showModal, val => { if (!val) { subLoading = false return } if (!props.draggable) {return } nextTick(() => { const oBox = document.getElementById('basic-modal') const oBar = document.getElementById('basic-modal-bar') startDrag(oBar, oBox) }) }) const cancelModal = () => { emit('negative-click') if (props.closeOnCancel) { showModal.value = false } } const confirmModal = () => { subLoading = true emit('positive-click') if (props.closeOnConfirm) { showModal.value = false } } </script>
Drag.ts
//获取相关CSS属性 const getCss = function (o, key) { return o.currentStyle ? o.currentStyle[key] : document.defaultView?.getComputedStyle(o, null)[key] } const params = { left: 0, top: 0, currentX: 0, currentY: 0, flag: false, } export const startDrag = function (bar, target, callback?) { const screenWidth = document.body.clientWidth // body当前宽度 const screenHeight = document.documentElement.clientHeight // 可见区域高度 const dragDomW = target.offsetWidth // 对话框宽度 const dragDomH = target.offsetHeight // 对话框高度 const minDomLeft = target.offsetLeft const minDomTop = target.offsetTop const maxDragDomLeft = screenWidth - minDomLeft - dragDomW const maxDragDomTop = screenHeight - minDomTop - dragDomH if (getCss(target, 'left') !== 'auto') { params.left = getCss(target, 'left') } if (getCss(target, 'top') !== 'auto') { params.top = getCss(target, 'top') } //o是移动对象 bar.onmousedown = function (event) { params.flag = true if (!event) { event = window.event //防止IE文字选中 bar.onselectstart = function () { return false } } const e = event params.currentX = e.clientX params.currentY = e.clientY } document.onmouseup = function () { params.flag = false if (getCss(target, 'left') !== 'auto') { params.left = getCss(target, 'left') } if (getCss(target, 'top') !== 'auto') { params.top = getCss(target, 'top') } } document.onmousemove = function (event) { const e: any = event || window.event if (params.flag) { const nowX = e.clientX const nowY = e.clientY const disX = nowX - params.currentX const disY = nowY - params.currentY let left = parseInt(params.left) + disX let top = parseInt(params.top) + disY // 拖出屏幕边缘 if (-left > minDomLeft) { left = -minDomLeft } else if (left > maxDragDomLeft) { left = maxDragDomLeft } if (-top > minDomTop) { top = -minDomTop } else if (top > maxDragDomTop) { top = maxDragDomTop } target.style.left = left + 'px' target.style.top = top + 'px' if (typeof callback === 'function') { callback((parseInt(params.left) || 0) + disX, (parseInt(params.top) || 0) + disY) } if (event.preventDefault) { event.preventDefault() } return false } } }
The text was updated successfully, but these errors were encountered:
No branches or pull requests
使用 card preset 封装了一下 modal,可拖动,可以省写几个属性。
x-n-modal.vue
Drag.ts
The text was updated successfully, but these errors were encountered: