<template>
<transition>
<div class="pl-dialog-wrap" v-show="visible">
<vue-draggable-resizable
ref="cmp-VueDraggable"
class="pl-dialog"
class-name-handle="pl-dialog-resize"
:w="w"
:h="h"
:z="zindex"
:minWidth="width"
:minHeight="height"
:x="x"
:y="y"
@dragging="onDrag"
@resizing="onResize"
:parent="true"
:dragHandle="dragHandle"
:enableNativeDrag="true"
>
<div class="pl-dialog-head" ref="dom-head">
<div class="title">
{{title}}
</div>
<i class="icon-close iconfont close" @click="handleCancel"></i>
</div>
<div class="pl-dialog-body" ref="dom-body" :style="bdStyle">
<div class="pl-dialog-content" ref="dom-content">
<div v-html="content"></div>
<slot v-if="!content"></slot>
</div>
</div>
<div class="pl-dialog-foot" ref="dom-foot" v-if="hasfoot">
<slot name="footer">
<button class="pl-btn pl-btn-round" @click="handleCancel">取消</button>
<button class="pl-btn pl-btn-round pl-btn-primary" @click="handleOk">确定</button>
</slot>
</div>
</vue-draggable-resizable>
<div class="pl-dialog-shadow" v-if="shade"></div>
</div>
</transition>
</template>
<script>
//https://mauricius.github.io/vue-draggable-resizable/?path=/info/styling--style-resizing
import VueDraggableResizable from "vue-draggable-resizable";
export default {
components: {
VueDraggableResizable
},
data() {
return {
w: this.width,
h: this.height,
x: 0,
y: 0,
dragHandle: ".pl-dialog-head",
zindex: 10000,
bdStyle:{
height:null
},
visible:false,
content:null
};
},
props:{
title:{
type:String,
default:'提示'
},
width:{
type:Number,
default:200
},
height:{
type:Number,
default:200
},
offset:{
type:String,
default:''
},
hasfoot:{
type:Boolean,
default:true
},
shade:{
type:Boolean,
default:true
}
},
mounted() {
document.body.appendChild(this.$el);
},
updated(){
this.resizeBody();
},
beforeDestroy(){
this.$el.remove();
},
methods: {
winResize(){
let parentW = document.documentElement.offsetWidth,
parentH = document.documentElement.offsetHeight || 0;
this.winWidth=parentW;
this.winHeight=parentH;
},
setContent(html){
this.content = html;
},
show(){
//v-if="visible" 显示会准 v-show会不准
this.visible=true;
this.x = (document.documentElement.offsetWidth - this.w)/2;
this.y = (document.documentElement.offsetHeight - this.h)/2;
if(this.offset=='rb'){
this.x = (document.documentElement.offsetWidth - this.w);
this.y = (document.documentElement.offsetHeight - this.h);
}
this.$nextTick(r=>{
//因为不会准 所以 重新计算
let dragable = this.$refs['cmp-VueDraggable'];
dragable.resetBoundsAndMouseState();
dragable.rawWidth = this.w;
dragable.rawHeight = this.h;
dragable.rawLeft = this.x;
dragable.rawTop = this.y;
dragable.left = this.x;
dragable.top = this.y;
[dragable.parentWidth, dragable.parentHeight] = dragable.getParentSize();
dragable.rawRight = dragable.parentWidth - dragable.rawWidth - dragable.rawLeft
dragable.rawBottom = dragable.parentHeight - dragable.rawHeight - dragable.rawTop
})
},
hide(){
this.visible=false;
},
resizeBody(){
if(!this.$refs['dom-head'])return;
const headRect = this.$refs['dom-head'].getBoundingClientRect();
const footRect = this.$refs['dom-foot'].getBoundingClientRect();
this.bdStyle.height = (this.h - headRect.height - footRect.height)+'px';
},
onResize: function(x, y, width, height) {
this.x = x;
this.y = y;
this.w = width;
this.h = height;
this.resizeBody();
},
onDrag: function(x, y) {
this.x = x;
this.y = y;
},
handleOk(){
let backVal = this.$emit('onOk');
this.hide();
},
handleCancel(){
this.$emit('onCancel');
this.hide();
}
}
};
</script>
<style lang="less">
.pl-dialog-wrap {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
.pl-dialog-shadow {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 10;
background: rgba(0, 0, 0, 0.3);
}
.pl-dialog {
background: #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
position: relative;
>.pl-dialog-head {
padding: 15px 10px;
border-top: 2px #0066cc solid;
background: #efefef;
cursor: move;
height: 16px;
overflow: hidden;
> .close {
position: absolute;
right: 8px;
top: 12px;
font-size: 24px;
color:#666;
cursor: pointer;
&:hover{
color:red;
transform: rotate(-90);
-webkit-transition: all 300ms linear;
-ms-transition: all 300ms linear;
transition: all 300ms linear;
}
}
}
>.pl-dialog-body {
overflow: auto;
.pl-dialog-content{
padding: 8px;
}
}
>.pl-dialog-foot{
height: 35px;
overflow: hidden;
padding: 10px;
text-align: right;
background-color:#f3f3f3;
.pl-btn+.pl-btn{
margin-left: 15px;
}
}
.pl-dialog-resize {
position: absolute;
height: 4px;
width: 4px;
display: block!important;
}
.pl-dialog-resize-tl {
top: 0px;
left: 0px;
cursor: nw-resize;
}
.pl-dialog-resize-tm {
top: 0;
left: 4px;
right:4px;
width:auto;
cursor: n-resize;
}
.pl-dialog-resize-tr {
top: 0;
right:0;
cursor: ne-resize;
}
.pl-dialog-resize-ml {
top: 4px;
bottom:4px;
left: 0;
height: auto;
cursor: w-resize;
}
.pl-dialog-resize-mr {
top: 4px;
bottom: 4px;
right: 0;
height: auto;
cursor: e-resize;
}
.pl-dialog-resize-bl {
bottom: 0;
left: 0;
cursor: sw-resize;
}
.pl-dialog-resize-bm {
bottom: 0;
left: 4px;
right: 4px;
width:auto;
cursor: s-resize;
}
.pl-dialog-resize-br {
bottom: 0;
right: 0;
cursor: se-resize;
}
}
</style>