After Width: | Height: | Size: 888 B |
After Width: | Height: | Size: 598 B |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 809 B |
After Width: | Height: | Size: 529 B |
After Width: | Height: | Size: 672 B |
After Width: | Height: | Size: 634 B |
After Width: | Height: | Size: 620 B |
After Width: | Height: | Size: 768 B |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 836 B |
After Width: | Height: | Size: 51 KiB |
After Width: | Height: | Size: 29 KiB |
@ -0,0 +1,133 @@ |
|||||
|
<template> |
||||
|
<a-modal |
||||
|
class="my-modal" |
||||
|
ref="modalRef" |
||||
|
:wrap-style="{ overflow: 'hidden' }" |
||||
|
@ok="handleOk" |
||||
|
:mask="mask" |
||||
|
:width="width" |
||||
|
> |
||||
|
<slot /> |
||||
|
<template #title> |
||||
|
<div ref="modalTitleRef" class="title"> |
||||
|
{{ title }} |
||||
|
</div> |
||||
|
</template> |
||||
|
<template #modalRender="{ originVNode }"> |
||||
|
<div :style="transformStyle"> |
||||
|
<component :is="originVNode" /> |
||||
|
</div> |
||||
|
</template> |
||||
|
<template #footer> |
||||
|
<slot name="footer" /> |
||||
|
</template> |
||||
|
</a-modal> |
||||
|
</template> |
||||
|
<script lang="ts" setup> |
||||
|
import { ref, computed, CSSProperties, watch, watchEffect } from 'vue'; |
||||
|
import { useDraggable } from '@vueuse/core'; |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
allowDrag: { |
||||
|
type: Boolean, |
||||
|
default: true, |
||||
|
}, |
||||
|
title: { |
||||
|
type: String, |
||||
|
default: '弹窗', |
||||
|
}, |
||||
|
mask: { |
||||
|
type: Boolean, |
||||
|
default: true, |
||||
|
}, |
||||
|
width: { |
||||
|
type: String || Number, |
||||
|
default: '520px', |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
const emits = defineEmits(['confirm', 'cancel']); |
||||
|
|
||||
|
const modalTitleRef = ref<HTMLElement>(); |
||||
|
|
||||
|
const { x, y, isDragging } = useDraggable(modalTitleRef); |
||||
|
|
||||
|
const handleOk = (e: MouseEvent) => { |
||||
|
emits('confirm', e); |
||||
|
}; |
||||
|
|
||||
|
// 拖拽操作 |
||||
|
const startX = ref<number>(0); |
||||
|
const startY = ref<number>(0); |
||||
|
const startedDrag = ref(false); |
||||
|
const transformX = ref(0); |
||||
|
const transformY = ref(0); |
||||
|
const preTransformX = ref(0); |
||||
|
const preTransformY = ref(0); |
||||
|
const dragRect = ref({ left: 0, right: 0, top: 0, bottom: 0 }); |
||||
|
watch([x, y], () => { |
||||
|
if (!startedDrag.value) { |
||||
|
startX.value = x.value; |
||||
|
startY.value = y.value; |
||||
|
const bodyRect = document.body.getBoundingClientRect(); |
||||
|
const titleRect = modalTitleRef.value!.getBoundingClientRect(); |
||||
|
dragRect.value.right = bodyRect.width - titleRect.width; |
||||
|
dragRect.value.bottom = bodyRect.height - titleRect.height; |
||||
|
preTransformX.value = transformX.value; |
||||
|
preTransformY.value = transformY.value; |
||||
|
} |
||||
|
startedDrag.value = true; |
||||
|
}); |
||||
|
watch(isDragging, () => { |
||||
|
if (!isDragging) { |
||||
|
startedDrag.value = false; |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
watchEffect(() => { |
||||
|
if (startedDrag.value && props.allowDrag) { |
||||
|
transformX.value = |
||||
|
preTransformX.value + |
||||
|
Math.min(Math.max(dragRect.value.left, x.value), dragRect.value.right) - |
||||
|
startX.value; |
||||
|
transformY.value = |
||||
|
preTransformY.value + |
||||
|
Math.min(Math.max(dragRect.value.top, y.value), dragRect.value.bottom) - |
||||
|
startY.value; |
||||
|
} |
||||
|
}); |
||||
|
const transformStyle = computed<CSSProperties>(() => { |
||||
|
return { |
||||
|
transform: `translate(${transformX.value}px, ${transformY.value}px)`, |
||||
|
}; |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less"> |
||||
|
.my-modal { |
||||
|
&.ant-modal { |
||||
|
.ant-modal-content { |
||||
|
width: 1000px; |
||||
|
background: url('@/assets/modal/model-bg.png') no-repeat 0 0/100% 100%; |
||||
|
.ant-modal-close { |
||||
|
top: 26px; |
||||
|
} |
||||
|
.ant-modal-header { |
||||
|
min-height: 50px; |
||||
|
background: url('@/assets/modal/header-bg.png') no-repeat 0 0/100% 100%; |
||||
|
|
||||
|
.ant-modal-title { |
||||
|
padding-left: 2vmin; |
||||
|
.title { |
||||
|
color: white; |
||||
|
line-height: 34px; |
||||
|
width: 100%; |
||||
|
cursor: move; |
||||
|
font-size: 30px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,126 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<MyModal v-model:open="open" title="消防栓" @confirm="handleOk" :mask="false"> |
||||
|
<div class="board-container"> |
||||
|
<div class="board-base"> |
||||
|
<ul class="info"> |
||||
|
<li> |
||||
|
<img src="@/assets/board/No.png" /> |
||||
|
<span class="label">编号</span> |
||||
|
<span class="value">鄂A39856</span> |
||||
|
</li> |
||||
|
<li> |
||||
|
<img src="@/assets/board/type.png" /> |
||||
|
<span class="label">规格型号</span> |
||||
|
<span class="value">消防栓</span> |
||||
|
</li> |
||||
|
<li> |
||||
|
<img src="@/assets/board/num.png" /> |
||||
|
<span class="label">数量</span> |
||||
|
<span class="value">2个</span> |
||||
|
</li> |
||||
|
<li> |
||||
|
<img src="@/assets/board/address.png" /> |
||||
|
<span class="label">储备地点</span> |
||||
|
<span class="value">加油站</span> |
||||
|
</li> |
||||
|
<li> |
||||
|
<img src="@/assets/board/people.png" /> |
||||
|
<span class="label">联系人</span> |
||||
|
<span class="value">李某某</span> |
||||
|
</li> |
||||
|
<li> |
||||
|
<img src="@/assets/board/phone.png" /> |
||||
|
<span class="label">电话</span> |
||||
|
<span class="value">13789553656</span> |
||||
|
<span class="call">拨打</span> |
||||
|
</li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
</div> |
||||
|
</MyModal> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts" setup name=""> |
||||
|
import { ref, computed, CSSProperties, watch, watchEffect } from 'vue'; |
||||
|
import { RadioChangeEvent } from 'ant-design-vue'; |
||||
|
import { ColumnType } from 'ant-design-vue/es/table'; |
||||
|
import MyModal from '@/components/MyModal.vue'; |
||||
|
|
||||
|
const open = ref<boolean>(false); |
||||
|
|
||||
|
const handleOk = (e: MouseEvent) => { |
||||
|
console.log(e); |
||||
|
open.value = false; |
||||
|
}; |
||||
|
|
||||
|
const editRef = ref(); |
||||
|
|
||||
|
function openEdit() { |
||||
|
editRef.value.open = true; |
||||
|
} |
||||
|
|
||||
|
defineExpose({ |
||||
|
open, |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less" scoped> |
||||
|
/* 修改表格样式 */ |
||||
|
:deep(.ant-table) { |
||||
|
font-size: 30px; |
||||
|
color: white; |
||||
|
} |
||||
|
|
||||
|
:deep(.ant-table-thead > tr > th) { |
||||
|
color: white; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
|
||||
|
:deep(.ant-btn-link) { |
||||
|
font-size: 30px; |
||||
|
padding: 0 4px; |
||||
|
} |
||||
|
|
||||
|
.board-container { |
||||
|
width: 100%; |
||||
|
height: 500px; |
||||
|
|
||||
|
.board-base { |
||||
|
.info { |
||||
|
padding: 15px 0 0 30px; |
||||
|
& > li { |
||||
|
width: 100%; |
||||
|
padding: 5px 0 20px 0; |
||||
|
vertical-align: middle; |
||||
|
font-size: 32px; |
||||
|
img{ |
||||
|
width: 40px; |
||||
|
height: 40px; |
||||
|
} |
||||
|
.label { |
||||
|
width: 30%; |
||||
|
display: inline-block; |
||||
|
margin-left: 10px; |
||||
|
color: white; |
||||
|
} |
||||
|
.value { |
||||
|
|
||||
|
color: #56c5ff; |
||||
|
} |
||||
|
.call{ |
||||
|
color: white; |
||||
|
height: 40px; |
||||
|
width: 100px; |
||||
|
background: url('@/assets/board/callBg.png') no-repeat 0 0/100% 100%; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.base-edit { |
||||
|
padding-top: 10px; |
||||
|
} |
||||
|
} |
||||
|
</style> |