創(chuàng)建一個公用的彈出框組件,包括消息彈出框,確認彈出框,自定義內(nèi)容彈出框
一、創(chuàng)建
1、創(chuàng)建一個基礎(chǔ)彈出框:dialog-base.vue
<template>
<div class="dialog-pop" v-bind:data-level="levelNum" v-bind:style="'z-index:'+zIndex" v-bind:ref="'dialog-'+levelNum">
<div class="dialog-pop-bg"></div>
<div v-bind:class="'dialog-pop-panel '+umMoveClass" v-bind:style="'width:'+initWidth+';height:'+initHeight+';top:'+top+'px;left:'+left+'px;min-height:'+minHeight+';min-width:'+minWidth+';'">
<div class="dialog-pop-panelmain">
<div class="dialog-pop-top">
<span class="dialog-pop-title">{{title}}</span>
<button class="dialog-pop-close" type="button" v-on:click.stop="closedialog"></button>
<button class="dialog-pop-full" type="button" v-on:click.stop="fullScreenCallback" v-if="fullScreen"></button>
<div v-drag="greet" v-bind:style="'height: 100%;position: absolute;top:0;left: 0;right:'+(fullScreen?'60':'30')+'px;'"></div>
</div>
<div class="dialog-pop-body" >
<dialog-message v-if="dialogType=='0'" v-bind:options="options" v-bind:message="message" ></dialog-message>
<dialog-confirm v-if="dialogType=='1'" v-bind:options="options" v-bind:message="message"></dialog-confirm>
<component :is="message" v-if="dialogType=='2'"></component>
</div>
</div>
</div>
</div>
</template>
<script>
import Vue from 'vue';
import '../../css/utils/popupWindow.css'
import '../../css/utils/botton.css'
import message from '../../vue/component/dialog-message.vue';
import confirm from '../../vue/component/dialog-confirms.vue';
Vue.directive('drag',//彈出框拖動指令
{bind:function (el, binding) {
let oDiv = el; //當前元素
let self = this; //上下文
oDiv.onmousedown = function (e) {
let parent=e.target.parentNode.parentNode.parentNode;
//鼠標按下,計算當前元素距離可視區(qū)的距離
let disX = e.clientX - parent.offsetLeft;
let disY = e.clientY - parent.offsetTop;
document.onmousemove = function (e) {
//通過事件委托,計算移動的距離
let l = e.clientX - disX;
let t = e.clientY - disY;
//將此時的位置傳出去
binding.value({x:l,y:t})
};
document.onmouseup = function (e) {
document.onmousemove = null;
document.onmouseup = null;
};
};
}
}
);
export default {
name: 'dialog-base',
data () {
return {
dialogType:"0",//彈出框類型:0:消息彈出,1:確認彈出,2::自定義彈出
options:{},//各種類型彈出框特有參數(shù)
initHeight:"",//初始化高度
initWidth:"400px",//初始化寬度
minHeight:"",//最小高度
minWidth:"",//最小寬度
levelNum:0,//層級
top:0,//位置;x
left:0,//位置:y
title:'提示',//彈出框標題
message:null,//彈出框內(nèi)容
fullScreen:false,//是否全屏
zIndex:-1,//顯示層級
oldPosition:{},//存儲初始位置
umMoveClass:''
}
},
components:{
"dialog-message":message,
"dialog-confirm": confirm,
},
mounted () {
this.fullScreen=this.options&&this.options.fullScreen?true:false;
this.minHeight=this.options&&this.options.minHeight?this.options.minHeight:"";
this.minWidth=this.options&&this.options.minWidth?this.options.minWidth:"";
//DOM渲染完成
this.$nextTick(function () {
this.windowResize();
});
window.onresize = (function resize() {
this.windowResize();
}).bind(this);
},
methods: {
greet(val){
let x=val.x;
let y=val.y;
if(x<0)x=0;
if(y<0)y=0;
this.left=x;
this.top=y;
},
closedialog(e){
if (this.options && typeof this.options.closeCallback == "function") {
this.options.closeCallback();
}
let pop=this.$refs['dialog-'+this.levelNum];
if(pop){
document.querySelector('body').removeChild(pop);
}
},
//窗口改變時間
windowResize(){
if(this.umMoveClass){//如果為最大化窗口,窗口樣式不需改變,僅調(diào)用改變窗口的回調(diào)函數(shù)
if (this.options && typeof this.options.fullScreenCallback == "function") {
this.options.fullScreenCallback();
}
return;
}
let winWidth=document.documentElement.clientWidth;
let winHeight=document.documentElement.clientHeight;
let width=this.$refs['dialog-'+this.levelNum].getElementsByClassName("dialog-pop-panel")[0].offsetWidth;
let height=this.$refs['dialog-'+this.levelNum].getElementsByClassName("dialog-pop-panel")[0].offsetHeight;
this.top= Math.max(20,(winHeight-height)/2-10);
this.left=(winWidth-width)/2;
if(this.top<0)this.top=0;
if(this.left<0)this.left=0;
this.zIndex=1000+this.levelNum*100;
this.oldPosition={
oldHeigth:this.initHeight,
oldWidth:this.initWidth,//初始化寬度
oldtop:this.top,//位置;x
oldleft:this.left,//位置:y
}
},
//全屏或者恢復(fù)彈窗大小是的回調(diào)
fullScreenCallback(){
if (this.options && typeof this.options.fullScreenCallback == "function") {
this.options.fullScreenCallback();
}
if(this.umMoveClass){//已經(jīng)是最大化窗口,點擊后需要恢復(fù)正常大小
this.umMoveClass='';
this.top=this.oldPosition.oldtop;
this.left=this.oldPosition.oldleft;
this.initWidth=this.oldPosition.oldWidth;
this.initHeight=this.oldPosition.oldHeigth;
}else{
this.umMoveClass='dialog-pop-ummove';
this.top=0;
this.left=0;
this.initWidth="100%";
this.initHeight="100%";
}
}
}
}
</script>
2、創(chuàng)建一個消息彈出框:dialog-message.vue
<template>
<div class="dialog-msg">
<div class="dialogmsg-content">{{message}}</div>
<i v-bind:class="'dialogicon '+iClass"></i>
<div class="dialogmsg-bottom">
<button class="dialogbtn-detail" type="button" v-if="options.detailMessage!=''" v-on:click="showDetail"><i v-bind:class="detailClass"></i>顯示詳細信息</button>
<button class="mt-btn__type1 dialogbtn-ok" type="button" v-on:click="closedialog">確認</button>
<transition name="fade">
<div class="dialogmsg-detail" v-if="isShowDetail" v-bind:style="'overflow:'+overflow">
{{options.detailMessage}}
</div>
</transition>
</div>
</div>
</template>
<script>
export default {
name: 'dialog-message',
props:{
message:{
type:String,
required:true
},
options:{
type:Object,
required:true,
}
},
data () {
return {
isShowDetail:false,
levelNum:20,
iClass:'dialogicon-1',
detailClass:'dialogbtn-ddown',
overflow:'hidden'
}
},
mounted () {
if(this.options&&this.options.iType){
this.iClass="dialogicon-"+this.options.iType;
}
},
methods: {
closedialog:function () {
if(this.options&&typeof this.options.callbackMessageOK === "function"){
this.options.callbackMessageOK(111);
}
this.$parent.closedialog();
},
showDetail:function(){
if(this.isShowDetail){
this.isShowDetail=false;
this.overflow="hidden";
this.detailClass="dialogbtn-ddown"
}else{
this.isShowDetail=true;
this.detailClass="dialogbtn-dup";
this.overflow="auto";
}
}
}
}
</script>
2、創(chuàng)建一個確認彈出框:dialog-confirms.vue
<template>
<div class="dialog-msg">
<div class="dialogconf-content">
{{message}}
</div>
<i class="dialogicon dialogicon-4"></i>
<div class="dialogconf-bottom">
<button class="mt-btn__type1 dialogbtn-yes" type="button" v-on:click="yesCallbackFunction"> {{yesText}} </button>
<button class="mt-btn__type3 dialogbtn-no" type="button" v-on:click="noCallbackFunction"> {{noText}} </button>
</div>
</div>
</template>
<script>
export default {
name: 'dialog-confirm',
props:{
message:{
type:String,
required:true
},
options:{
type:Object,
required:true,
}
},
data () {
return {
yesText:'確認',
noText:'取消',
confirmData:null,
}
},
mounted () {
if(this.options&&this.options.yesText){
this.yesText=this.options.yesText;
}
if(this.options&&this.options.noText){
this.noText=this.options.noText;
}
if(this.options&&this.options.data){
this.confirmData=this.options.data;
}
this.iClass="dialogicon-"+this.iType;
},
methods: {
yesCallbackFunction () {
try{
if(this.options&&typeof this.options.yesCallbackFunction === "function"){
let result=this.options.yesCallbackFunction(this.confirmData);
if (typeof result == "boolean" && result == false) {
return;
}
}
}
catch(e){
}
this.closeDialog();
},
noCallbackFunction(){
try{
if(this.options&&typeof this.options.noCallbackFunction === "function"){
let result=this.options.noCallbackFunction(this.confirmData);
if (typeof result == "boolean" && result == false) {
return;
}
}
}
catch(e){
}
this.closeDialog();
},
closeDialog(){
this.confirmData=null;
this.$parent.closedialog();
}
},
}
</script>
3、創(chuàng)建一個自定義出框:自定義.vue
????創(chuàng)建一個任意內(nèi)容vue文件
二、調(diào)用
1、創(chuàng)建供調(diào)用的接口文件:dialogUtil.js
import Vue from 'vue'
import Message from '../../vue/component/dialog-base.vue'
export default{
installDialog(){
return {
message:this.installMessage.bind(this),
confirm:this.installConfirm.bind(this),
subPop:this.installSubPop.bind(this),
}
},
/*
* 消息彈窗框
* options={
* title:'',
* message:'',
* options:{
* detailMessage:'',
* iType:'1',//枚舉值:1,2,3(警告類型圖標,提示類型圖標等,配合css使用)
* callbackMessageOK:func
* },
* }
* */
installMessage(options) {
options.dialogType='0';
options.initWidth="400px";
options.levelNum=20;
this.initBase(options);
},
/*
* 確認彈窗框
* options={
* title:"",
* message:"",
* options:{
* yesCallbackFunction:func,
* noCallbackFunction:func,
* yesText:'',
* noText:'',
* data:{} //點擊確認傳給回調(diào)的數(shù)據(jù)
* },
* }
* */
installConfirm(options) {
options.dialogType='1';
options.initWidth="400px";
options.levelNum=10;
this.initBase(options);
},
/* 彈出框
* 包含:子彈出窗(levelNum為0-9),通知框,確認框,加載中信息框
* 參數(shù):
* options={
* titleText:string,標題
* elemText:string,彈窗的html內(nèi)容
* levelNum:int,Z軸上的層,分0-9層(可缺,默認值為0)
* initWidth: string('400px'),初始化寬度(可缺)(此參數(shù)在手機瀏覽器上不生效,采用固定值:96%)
* initHeight: string,初始化高度(可缺)
* options:{
* minWidth: string,最小寬度,僅用于手機瀏覽器(可缺)
* minHeight: string,最小高度,僅用于手機瀏覽器(可缺)
* fullScreen:bool,是否顯示全屏按鈕(可缺)
* fullScreenCallback:func,點擊全屏按鈕的回調(diào)函數(shù)(可缺)
* closeCallback:func,點擊窗口關(guān)閉事件的回調(diào)函數(shù)(可缺)
* }
* }
*/
installSubPop(options) {
options.dialogType='2';
options.levelNum=0;
this.initBase(options);
},
initBase(options){
var message = Vue.extend(Message)
var component = new message({
data: options
}).$mount()
document.querySelector('body').appendChild(component.$el)
}
}
2、引入消息彈窗組件
import dialogMessage from '../utils/dialogUtil.js';
Vue.prototype.$installdialog = dialogMessage.installDialog();
3、使用彈窗
//消息彈窗
let options= {
title: "提示",
message: "內(nèi)容",
options: {
detailMessage: "detail",
iType: "2",
//callbackMessageOK:this.yesCallback.bind(this)
}
};
this.$installdialog.message(options);
//確認彈窗
let options={
title:"提示",
message:"確定是否?",
options:{
yesCallbackFunction:this.yesCallbackFunction,
// noCallbackFunction:this.noCallbackFunction,
// yesText:'',
// noText:'',
data:{
test:'111'
}
}
}
this.$installdialog.confirm(options);
//自定義彈窗
import page from "./page.vue";
let options={
title:"彈出",
message:page,
initWidth:"300px",
initHeight:"200px",
options:{
minWidth:"400px",
minHeight:"300px",
fullScreen:true,
fullScreenCallback:this.fullScreenCallback,
closeCallback:this.yesCallback,
}
}
this.$installdialog.subPop(options);
????碰到一個問題 如果把v-drag 綁定到dialog-pop-top上,點擊關(guān)閉按鈕時會先觸發(fā)drag事件,再點擊一次才會正常關(guān)閉,阻止冒泡也沒用,不知道是何原因。。。。
????新手入門,歡迎指正,接受批評?。。?!