.shadow{
background-color:rgba(0,0,0,0.5);
display:table;
height:100%;
left:0;
position:fixed;
top:0;
transition:opacity0.3sease;
width:100%;
z-index:50;
}
.modal{
display:table-cell;
vertical-align:middle;
overflow-x:hidden;
position:fixed;
background-color:white;
box-shadow:rgba(0,0,0,0.33)0px2px8px;
border-radius:5px;
outline:0px;
overflow:hidden;
transition:all0.3sease;
width:600px;
height:400px;
top:50%;
left:50%;
margin-top:-200px;
margin-left:-300px;
}
.header{
align-items:center;
background-color:#62a39e;
box-shadow:01px1pxrgba(0,0,0,0.16);
color:#fff;
font-weight:bold;
display:-ms-flexbox;
display:flex;
height:3.5rem;
padding:01.5rem;
position:relative;
z-index:1;
}
.body{
align-items:center;
padding:1.5rem;
}
.footer{
justify-content:flex-end;
padding:1.5rem;
position:absolute;
bottom:0;
width:100%;
float:right;
}
.item{
color:white;
text-align:center;
border-radius:5px;
padding:10px;
cursor:pointer;
display:inline-block;
}
.info{
background-color:#2196f3;
}
.success{
background-color:#62a39e;
}
.red{
background-color:#e95358;
}
.smSize{
height:200px;
}
首先分析一下第一种方式:调用者需要在组件外部v-model上绑定一个变量(例中为showModal)来指示弹窗是否显示,显示的时候需要在组件外部手动设置this.showModal=true,组件内部props定义一个属性来接这个值为value:{type:Boolean},同时在组件内部在用声明一个变量用来同步外部传进来的props值默认值为showModal:this.value(内部声明的值也叫了showModal),在watch中监听进行同步watch:{value(newVal){this.showModal=newVal}};然后把组件内部的这个showModal值绑定在需要显示或者隐藏的DOM元素上。向外抛出事件的时候是在点击组件内部的确定与关闭按钮时候
makeSure(){
this.$emit("on-ok");
this.$emit("input",false);
},
makeCancel(){
this.$emit("on-cancel");
this.$emit("input",false);
}
this.$emit("on-ok");this.$emit("on-cancel");这两句的是向外抛出事件在组件外部@接一下然后写自己需要的回调函数。这时就可以实现弹窗的显示与隐藏了,你可能发现并没有一句代码去设置this.showModal=false;弹窗就隐藏了。主要是因为这几句代码v-model='showModal'和组件内部的props:{value:{type:Boolean}}this.$emit("input",false)。v-model其实是vue的语法糖,其实可以写为所以要求我们在组件内部必须规定props的名字必须为value,然后在组件内部触发确定或者取消的时候在组件内部触发this.$emit("input",false)这样实现了直接隐藏弹窗而不必打扰用户让用户在组件外部在手动将showModal置为false.
然后来看promise的方式:第一种方式传进来的值都通过props来接的,这种方式通过在组件内部定义了另一个对象来接传进来的值,
varinitOtherText={
sureText:"",
cancelText:"",
title:"",
small:false
};
otherText:JSON.parse(JSON.stringify(initOtherText)),
然后在menthods里定义了一个名为openModal的方法,然后把传进来的一系列参数赋值给组件内部的对象this.otherText={...otherText};this.showModal=true;并且将showModal置为true,然后每次触发的时候新建一个promise对象,里面的异步事件为点击确定和取消的两个点击事件,这里要操作DOM了
this.$refs["sure"].addEventListener("click",()=>{
this.showModal=false;
resolve("点击了确定");
});
获取确定按钮的DOM元素绑定点击事件,回调里将showModal置为false并且resolve,
this.$refs["cancel"].addEventListener("click",()=>{
this.showModal=false;
reject("点击了取消");
});
获取取消按钮的DOM绑定点击事件,回调里reject.
遇到的坑
这之前遇到了一个坑,因为第一次已经绑定了点击事件,第二次resolve和reject就会失败,本想取消一下绑定事件,但是因为将整个弹窗v-show="showModal"的原因整个DOM被display:none;了就不需要手动解绑了。第二个是关于用v-if还是v-show来隐藏弹窗,一开始用的是v-if但是发现在这步时
this.showModal=true;
varpms=newPromise((resolve,reject)=>{
this.$refs["sure"].addEventListener.xxx//省略
});
returnpms;
将showModal置为true时然后就去绑定事件这时候还没有DOM还没有解析玩DOM树上还没有,要不就得用this.$nextTick增加了复杂度,最后采用了v-show;
关于优先级问题
如果既在组件上用prop传了值(title,sureText之类的)如也在方法里传了
this.$refs["chat-modal"].openModal({
title:"服务小结",
sureText:"提交并结束",
cancelText:"取消"
}).then();
是以方法的优先级为高,在组件内部DOM元素上通过||设置了优先级,比如{{otherText.title||title}}有方法的值取方法的值,没有取props得值。
总结
以上所述是小编给大家介绍的以v-model与promise两种方式实现vue弹窗组件,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!