<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>