源碼下載
改組件繼承el-dialog組件百分之95屬性,可直接對<el-dialog>進(jìn)行替換。在項(xiàng)目中我的命名為:
SkDialog。廢話不多說,直接上代碼:
vue代碼:搞成組件,路徑隨意,推薦統(tǒng)一放在組件目錄下
<!--
@author: kzy;
-->
<template>
<el-dialog ref="skDialog"
custom-class="dialogHeightFull skDialog"
:title="title"
:fullscreen="fullFlag"
:visible.sync="dialogVisible"
:append-to-body="appendToBody"
:lock-scroll="lockScroll"
:modal-append-to-body="modalAppendToBody"
:close-on-click-modal="closeOnClickModal"
:close-on-press-escape="closeOnPressEscape"
:show-close="false"
:before-close="beforeClose"
:center="center"
:destroy-on-close="destroyOnClose"
:width="width"
:top="top"
v-if="dialogVisible"
v-sk-dialog-drag
@closed="closeSkDialog">
<div slot="title" class="skDialog-header">
<div class="skDialog-title"><span>{{title}}</span></div>
<div class="skDialog-icon">
<i :class="fullFlag? 'el-icon-copy-document' : 'el-icon-full-screen' " @click="IsFullscreen"></i>
<i class="el-icon-close" @click="closeSkDialog"></i>
</div>
</div>
<div class="el-dialog__body" v-if="rendered"><slot :style="{height:height}"></slot></div>
<div class="el-dialog__footer" v-if="$slots.footer">
<slot name="footer"></slot>
</div>
<div class="resize"></div>
</el-dialog>
</template>
<script>
export default {
name: 'SkDialog',
props: {
visible: {
type: Boolean,
default: false
},
titleVisible: {
type: Boolean,
default: true
},
width: {
type: String,
default: '50%'
},
height: {
type: String,
default: '100%'
},
top: {
type: String,
default: '30px'
},
title: {
type: String,
default: ''
},
isfullscreen: {
type: Boolean,
default: false // 默認(rèn)全屏
},
modal: {
type: Boolean,
default: true
},
modalAppendToBody: {
type: Boolean,
default: true
},
appendToBody: {
type: Boolean,
default: true
},
lockScroll: {
type: Boolean,
default: true
},
closeOnClickModal: {
type: Boolean,
default: false
},
closeOnPressEscape: {
type: Boolean,
default: false
},
showClose: {
type: Boolean,
default: true
},
customClass: {
type: String,
default: ''
},
beforeClose: Function,
center: {
type: Boolean,
default: false
},
destroyOnClose: Boolean
},
data() {
return {
full: false, // 全屏
}
},
computed: {
fullFlag: {
get: function() {
return this.full ?? this.isfullscreen;
},
set: function(n) {
return this.full
}
},
dialogVisible:{ //重新設(shè)置一個(gè)變量,接收父級傳遞的參數(shù),引用頁面需要使用語法糖,才能使用this.$emit('update:visible', false)對父組件值進(jìn)行更新
get:function(){
return this.visible
},
set :function(value){
this.$emit('update:visible', false)
}
},
rendered:{ //重新設(shè)置一個(gè)變量,接收父級傳遞的參數(shù)
get:function(){
return this.visible
},
}
},
mounted() {
},
methods: {
// 全屏 切換
IsFullscreen() {
let dialogDom = document.querySelector(".skDialog");
if (this.isfullscreen == true) {
this.full = this.full === null ? false : !this.full
} else {
this.full = this.full === null ? true : !this.full
dialogDom.style.top =`0px`;
dialogDom.style.left =`auto`;
}
// 傳過來的全屏鉤子函數(shù)
this.$emit('maxFun')
},
// 關(guān)閉
closeSkDialog() {
this.full = null
this.$emit('update:visible', false)
// 傳過來的關(guān)閉鉤子函數(shù)
this.$emit('closeFun')
}
},
watch:{
},
created() {
this.full = this.isfullscreen
},
}
</script>
<style scoped="scoped">
>>>.el-dialog__header {
background-color: #f2f2f2;
/* height: 48px; */
padding: 10px 20px 10px;
}
.skDialog-header {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.skDialog .skDialog-icon i {
display: inline-block;
height: 28px;
width: 28px;
line-height: 24px;
text-align: center;
border-radius: 50%;
cursor: pointer;
font-size: 22px;
}
.skDialog .skDialog-icon i:hover {
background-color: #ddd;
}
.skDialog .skDialog-icon i::before {
font-size: 80%;
}
>>>.skDialog.dialogHeightFull.el-dialog {
margin-bottom: 0;
/*overflow-y: hidden;*/
}
.el-dialog__wrapper{
/*overflow: hidden!important;*/
}
.resize{
position: absolute;
right: 0;
bottom: 0;
content: '';
width: 10px;
height: 10px;
cursor: se-resize;
}
</style>
拖動(dòng)及縮放操作js代碼:
/**
@author: kzy;
*/
import Vue from 'vue'
Vue.directive("SkDialogDrag", {
bind(el, binding, vnode, oldVnode) {
const windowW = document.body.clientWidth;
const windowH = document.body.clientHeight
//設(shè)置彈框可拉伸最小寬高
let minWidth = 400;
let minHeight = 300;
const dialogHeaderEl = el.querySelector(".el-dialog__header");
//彈窗
const dragDom = el.querySelector(".el-dialog");
//頭部加上可拖動(dòng)cursor
dialogHeaderEl.style.cursor = "move";
// 獲取style屬性
const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null);
let moveDown = e => {
// 鼠標(biāo)按下,計(jì)算當(dāng)前元素距離可視區(qū)的距離
const disX = e.clientX - dialogHeaderEl.offsetLeft;
const disY = e.clientY - dialogHeaderEl.offsetTop;
// 獲取到的值帶px 正則匹配替換
let styL, styT, styMT;
// 注意在ie中 第一次獲取到的值為組件自帶50% 移動(dòng)之后賦值為px
if (sty.left.includes("%")) {
styL = +document.body.clientWidth * (+sty.left.replace(/\%/g, "") / 100);
styT = +document.body.clientHeight * (+sty.top.replace(/\%/g, "") / 100);
} else {
styL = +sty.left.replace(/\px/g, "");
styT = +sty.top.replace(/\px/g, "");
styMT = +sty.marginTop.replace(/\px/g, "")
}
document.onmousemove = function (e) {
const titleH = dialogHeaderEl.offsetHeight;
// 通過事件委托,計(jì)算移動(dòng)的距離
let l = e.clientX - disX;
let t = e.clientY - disY;
// 移動(dòng)邊界處理
if (t < 0 && (t + styMT + styT) <= 0 || t < 0 && (styMT + styT) <= 0) {
t = -(styMT + styT);
} else if (t > 0 && t > (document.body.clientHeight - styMT - styT - titleH)) {
t = document.body.clientHeight - styMT - styT - titleH;
}
// 移動(dòng)當(dāng)前元素
dragDom.style.left = `${l + styL}px`;
dragDom.style.top = `${t + styT}px`;
};
document.onmouseup = function (e) {
document.onmousemove = null;
document.onmouseup = null;
};
};
dialogHeaderEl.onmousedown = moveDown;
dragDom.onmousemove = function (e) {
const dialogBODY = el.querySelector(".el-dialog__body");
const resizeDom= el.querySelector(".resize");
const titleH = dialogHeaderEl.offsetHeight;
dragDom.onmousedown = e => {
const clientX = e.clientX;
const clientY = e.clientY;
let elW = dragDom.clientWidth;
let elH = dragDom.clientHeight;
let EloffsetLeft = dragDom.offsetLeft;
let EloffsetTop = dragDom.offsetTop;
let ELscrollTop = el.scrollTop;
let resizeW = resizeDom.clientWidth, resizeH = resizeDom.clientHeight;
//判斷點(diǎn)擊的位置是不是為頭部
if (
clientX > EloffsetLeft &&
clientX < EloffsetLeft + elW &&
clientY > EloffsetTop &&
clientY < EloffsetTop + 100
) {
//如果是頭部
e.preventDefault(); // 移動(dòng)時(shí)禁用默認(rèn)事件
} else {
document.onmousemove = function (e) {
//鼠標(biāo)拖拽
if (
clientX > EloffsetLeft + elW - resizeW &&
clientX < EloffsetLeft + elW
) {
//往左拖拽
if (clientX > e.clientX) {
if (dragDom.clientWidth < minWidth) {
} else {
dragDom.style.width = elW - (clientX - e.clientX) * 2 + "px";
}
}
//往右拖拽
if (clientX <= e.clientX) {
let targetTW = elW + (e.clientX - clientX) * 2
targetTW > windowW ?
dragDom.style.width = windowW + "px" :
dragDom.style.width = targetTW + "px"
}
}
//底部鼠標(biāo)拖拽位置
if (
ELscrollTop + clientY > EloffsetTop + elH - resizeH &&
ELscrollTop + clientY < EloffsetTop + elH
) {
//往上拖拽
if (clientY > e.clientY) {
if (dragDom.clientHeight < minHeight) {
} else {
dragDom.style.height = elH - (clientY - e.clientY) * 1 + "px";
dialogBODY.style.height = elH - (clientY - e.clientY) * 1 - titleH + "px";
}
}
//往下拖拽
if (clientY <= e.clientY) {
e.clientY >= windowH ?
dragDom.style.height = windowH - dragDom.offsetTop + "px" :
dragDom.style.height = elH + (e.clientY - clientY) * 1 + "px";
dialogBODY.style.height = elH - (clientY - e.clientY) * 1 - titleH + "px";
}
}
};
//結(jié)束
document.onmouseup = function (e) {
document.onmousemove = null;
document.onmouseup = null;
};
}
};
};
}
});
export default Vue.directive('SkDialogDrag')
將skdialog.js注冊為指令:
目錄:
import SkDialogDrag from './dialog/skdialog'
const install = function(Vue) {
Vue.directive('SkDialogDrag', SkDialogDrag)
}
指令使用:(v-指令名稱(SkDialogDrag))
效果圖:
文章來源:http://www.zghlxwxcb.cn/news/detail-767979.html
注:吃水不忘挖井人,在?原作者wjqocean?的基礎(chǔ)之上改進(jìn)文章來源地址http://www.zghlxwxcb.cn/news/detail-767979.html
到了這里,關(guān)于基于element-ui el-dialog組件封裝,可縮放+可移動(dòng)的彈窗組件的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!