vue可改变大小的弹框 发表于 2018-12-07 思路: 在弹框四周拖拽改变大小的区域(上,下,左,右,左上,右上,左下,右下) 在上述区域的元素添加mousedown事件绑定resize函数 resize函数用来改变弹框大小 在遮罩层绑定mouseup事件, 用于释放onmousemove事件 源码: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229<template> <transition> <div class="dialog" v-show="visible" :style="{zIndex:zIndex}" @mouseup="mouseup()"> <div class="main" ref="main"> <div class="resizeT" @mousedown="resize($event,'T')"></div> <div class="resizeL" @mousedown="resize($event,'L')"></div> <div class="resizeB" @mousedown="resize($event,'B')"></div> <div class="resizeR" @mousedown="resize($event,'R')"></div> <div class="resizeTL" @mousedown="resize($event,'TL')"></div> <div class="resizeTR" @mousedown="resize($event,'TR')"></div> <div class="resizeBR" @mousedown="resize($event,'BR')"></div> <div class="resizeBL" @mousedown="resize($event,'BL')"></div> <div class="title" :class="{'hasName':!!name}"> {{name}} <a class="close" @click="hide();clickClose()"></a> </div> <div class="body" :style="{'width':width+'px','height':height+'px'}"> <slot></slot> </div> </div> </div> </transition></template><script> import {getNextZIndex} from '../../services/sharedService' export default { data() { return { closed: true, zIndex: -1, left: 0, right: 0, top: 0, bottom: 0, width: 0, height: 0 } }, // bodywidth,bodyheight 弹框初识宽高 props: ['name', 'visible', 'bodywidth', 'bodyheight'], created() { this.zIndex = getNextZIndex(); this.width = this.bodywidth this.height = this.bodyheight }, watch: { visible(val) { let robotRight = document.getElementById('robot-right') if (val) { this.closed = false; this.$emit('open'); document.body.style.overflow = 'hidden' robotRight && (robotRight.style.overflow = 'hidden') } else { if (!this.closed) this.$emit('close'); document.body.style.overflow = 'auto' robotRight && (robotRight.style.overflow = 'auto') } } }, methods: { // 改变大小 resize(re, type) { // 获取鼠标按下时的位置 let x = re.x let y = re.y let height = this.height let width = this.width // 在document.onmousemove的回调函数中处理弹框大小的变化 document.onmousemove = (e) => { switch (type) { case 'T': this.height = (height - 0) + (y - e.y) * 2 break case 'B': this.height = (height - 0) + (e.y - y) * 2 break case 'L': this.width = (width - 0) + (x - e.x) * 2 break case 'R': this.width = (width - 0) + (e.x - x) * 2 break case 'TL': this.height = (height - 0) + (y - e.y) * 2 this.width = (width - 0) + (x - e.x) * 2 break case 'TR': this.height = (height - 0) + (y - e.y) * 2 this.width = (width - 0) + (e.x - x) * 2 break case 'BR': this.height = (height - 0) + (e.y - y) * 2 this.width = (width - 0) + (e.x - x) * 2 break case 'BL': this.height = (height - 0) + (e.y - y) * 2 this.width = (width - 0) + (x - e.x) * 2 break } } }, mouseup() { // 释放onmousemove的回调函数 document.onmousemove = null }, close: function () { this.closed = true; }, hide(cancel) { if (cancel !== false) { this.$emit('update:visible', false); this.$emit('close'); this.$emit('closeReset', 'newData') this.closed = true; } }, clickClose() { this.$emit('clickClose'); } } }</script><style lang="less" scoped> .dialog { position: fixed; top: 0; left: 0; background-color: rgba(39, 49, 66, 0.72); z-index: 1000; overflow: auto; color: @text-black; height: 100%; width: 100%; .main { position: relative; background-color: white; top: 50%; left: 50%; transform: translate(-50%, -50%); display: inline-block; max-height: 100%; // 调节大小 .resizeT, .resizeL, .resizeB, .resizeR, .resizeTL, .resizeTR, .resizeBR, .resizeBL { position: absolute; overflow: hidden; } .resizeTL, .resizeTR, .resizeBR, .resizeBL { width: 8px; height: 8px; } .resizeT { width: 100%; height: 5px; top: 0; left: 0; cursor: n-resize; } .resizeL { width: 5px; height: 100%; top: 0; left: 0; cursor: w-resize; } .resizeR { width: 5px; height: 100%; top: 0; right: 0; cursor: e-resize; } .resizeB { width: 100%; height: 5px; bottom: 0; right: 0; cursor: s-resize; } .resizeTL { cursor: nw-resize; } .resizeTR { right: 0; cursor: ne-resize; } .resizeBR { right: 0; bottom: 0; cursor: se-resize; } .resizeBL { bottom: 0; cursor: sw-resize; } // 调节大小 --end .title { font-size: 14px; line-height: 14px; padding: 18px; .close { width: 30px; height: 30px; background: url('../assets/images/close.svg') no-repeat center center; display: inline-block; float: right; margin-top: -7px; } &.hasName { background: @back-grey; border-bottom: 1px solid @border-grey; } } .body { max-height: calc(100% - 100px); width: calc(100% - 60px); overflow: auto; background: white; } } }</style>