VUE2实现事件驱动弹窗示例
前几天想了解vue如何写弹窗组件
有以下两种可取的写法:
1.状态管理如果弹窗组件放在根组件,使用vuex来管理组件的show和hide。放在组件内,通过增加v-show或v-if来控制,可结合slot,定义不同需求的弹窗
2.事件管理注册一个全局事件来打开弹窗,传入需展示的文字和相关的逻辑控制,可结合promise,实现异步
觉得对用像confirme和propmt这类弹窗,还是事件驱动的好。最好就是能使用promise回调。
于是手痒就写了一个。下面是代码。
propmt.js
importVuefrom'vue'
importpromptComponentfrom'./prompt.vue'//引入弹窗的vue文件
constpromptConstructor=Vue.extend(promptComponent);//注册组件
letinstance=newpromptConstructor().$mount('');//获得组件的实例
document.body.appendChild(instance.$el);//将组件的element插入到body中
constAlert=(text,okText)=>{
if(instance.show===true){//防止多次触发
return;
}
//为弹窗数据赋值
instance.show=true;
instance.isAlert=true;
instance.okText=okText||'确定';
instance.message=text;
//返回一个promise对象,并为按钮添加事件监听
returnnewPromise(function(resolve,reject){
instance.$refs.okBtn.addEventListener('click',function(){
instance.show=false;
resolve(true);
})
})
};
constConfirm=(text,okText,cancelText)=>{
if(instance.show===true){
return;
}
instance.show=true;
instance.okText=okText||'确定';
instance.cancelText=cancelText||'取消';
instance.message=text;
returnnewPromise(function(resolve,reject){
instance.$refs.cancelBtn.addEventListener('click',function(){
instance.show=false;
resolve(false);
});
instance.$refs.okBtn.addEventListener('click',function(){
instance.show=false;
resolve(true);
})
})
};
constPrompt=(text,okText,inputType,defaultValue)=>{
if(instance.show===true){
return;
}
instance.show=true;
instance.isPrompt=true;
instance.okText=okText||'确定';
instance.message=text;
instance.inputType=inputType||'text';
instance.inputValue=defaultValue||'';
returnnewPromise(function(resolve,reject){
instance.$refs.okBtn.addEventListener('click',function(){
instance.show=false;
resolve(instance.inputValue);
})
})
};
export{Alert,Confirm,Prompt}
prompt.vue
.confirm-enter-active{ transition:all.2s; } .confirm-leave-active{ transition:opacity.2s; } .confirm-leave-to{ opacity:0; } .confirm-enter{ opacity:0; } .confirm{ position:relative; font-family:PingFangSC-Regular; font-size:17px; -webkit-user-select:none; user-select:none; //遮罩层样式 .masker{ position:fixed; top:0; left:0; width:100%; height:100%; background-color:rgba(0,0,0,.4); -webkit-transition:opacity.1slinear; transition:opacity.1slinear; z-index:100; } //入库数据错误样式 .box{ position:absolute; top:50%; left:50%; width:72%; -webkit-transform:translate(-50%,-50%); transform:translate(-50%,-50%); text-align:center; border-radius:12px; background-color:#fff; .message{ height:97px; line-height:24px; font-family:PingFangSC-Regular; font-size:17px; vertical-align:middle; color:#999; letter-spacing:-0.41px; p{ margin:20pxauto0auto; vertical-align:middle; } &::after{ content:''; height:100%; } } .prompt{ margin:20px0; width:100%; p{ margin:5pxauto; font-size:17px; line-height:24px; } input{ margin:5pxauto; border:1pxsolid#333; border-radius:6px; width:100px; height:30px; font-size:14px; line-height:20px; text-align:center; } } .button-group{ a{ width:calc(50%-0.5px); text-align:center; font-size:17px; line-height:43px; color:blue; } .max-width{ width:100%!important;; } } } } {{message}}
{{message}}