.confirm-enter-active{tran位置:所有.2s;}.confirm-leave-active{transition:opacity.2s;}.confirm-leave-to{不透明度:0;}.confirm-enter{不透明度:0;}.confirm{位置:相对;字体系列:PingFangSC-Regular;字体大小:17px;-webkit-用户选择:无;用户选择:无;//遮罩层样式.masker{position:fixed;顶部:0;左:0;宽度:100%;高度:100%;背景色:rgba(0,0,0,.4);-webkit-transition:opacity.1slinear;过渡:不透明度.1s线性;z-指数:100;}//入库数据错误格式.box{position:absolute;顶部:50%;左:50%;宽度:72%;-webkit-transform:翻译(-50%,-50%);转换:翻译(-50%,-50%);文本对齐:居中;边界半径:12px;背景色:#fff;.message{高度:97px;行高:24px;字体系列:PingFangSC-Regular;字体大小:17px;垂直对齐:中间;颜色:#999;字母间距:-0.41px;p{边距:20px自动0自动;垂直对齐:中间;}&::after{内容:'';高度:100%;}}.prompt{边距:20px0;宽度:100%;p{边距:5px自动;字体大小:17px;行高:24px;}input{margin:5pxauto;边框:1px实心#333;边界半径:6px;宽度:100px;高度:30px;字体大小:14px;行高:20px;文本对齐:居中;}}.button-group{a{width:calc(50%-0.5px);文本对齐:居中;字体大小:17px;行高:43px;颜色:蓝色;}.max-width{width:100%!important;;}}}}前几天想知道怎么用vue写弹窗组件。我参考了知乎上的回答:https://www.zhihu.com/questio...有两个可取的:写法:1.状态管理如果弹窗组件放在根组件中,使用vuex来管理组件的显示和隐藏。放在组件中,通过添加v-show或者v-if来控制。可以结合slot来定义不同需求的弹窗。2.事件管理注册一个打开弹窗的全局事件,传入要显示的文本及相关逻辑控件,可以结合promise实现异步。我觉得还是用confirme、propmt这种事件驱动的弹窗比较好。最好的事情是能够使用承诺回调。于是手痒写了一篇。下面是代码。propmt.jsimportVuefrom'vue'importpromptComponentfrom'./prompt.vue'//导入弹窗的Vue文件constpromptConstructor=Vue.extend(promptComponent);//注册组件letinstance=newpromptConstructor().$mount('');//获取组件的实例document.body.appendChild(instance.$el);//将组件的元素插入bodyconstAlert=(text,okText)=>{if(instance.show===true){//防止return被多次触发;}//分配弹出数据instance.show=true;instance.isAlert=true;instance.okText=okText||'确定';instance.message=文本;//返回一个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=文本;返回新的承诺(函数(解决,拒绝){实例。$refs.cancelBtn.addEventListener('点击',函数(){实例.show=false;解决(假);});实例。$refs.okBtn.addEventListener('click',function(){instance.show=false;resolve(true);})})};constPrompt=(text,okText,inputType,defaultValue)=>{if(instance.show===true){返回;}instance.show=true;instance.isPrompt=true;instance.okText=okText||'确定';instance.message=文本;instance.inputType=输入类型||'文本';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{tran位置:所有.2s;}.confirm-leave-active{transition:opacity.2s;}.confirm-leave-to{不透明度:0;}.confirm-enter{不透明度:0;}.confirm{位置:相对;字体系列:PingFangSC-Regular;字体大小:17px;-webkit-用户选择:无;用户选择:无;//遮罩层样式.masker{position:fixed;顶部:0;左:0;宽度:100%;高度:100%;背景色:rgba(0,0,0,.4);-webkit-transition:opacity.1slinear;过渡:不透明度.1s线性;z-指数:100;}//入库数据错误格式.box{position:absolute;顶部:50%;左:50%;宽度:72%;-webkit-transform:翻译(-50%,-50%);转换:翻译(-50%,-50%);文本对齐:居中;边界半径:12px;背景色:#fff;.message{高度:97px;行高:24px;字体系列:PingFangSC-Regular;字体大小:17px;垂直对齐:中间;颜色:#999;字母间距:-0.41px;p{边距:20px自动0自动;垂直对齐:中间;}&::after{内容:'';高度:100%;}}.prompt{边距:20px0;宽度:100%;p{边距:5px自动;字体大小:17px;行高:24px;}input{margin:5pxauto;边框:1px实心#333;边界半径:6px;宽度:100px;高度:30px;字体大小:14px;行高:20px;文本对齐:居中;}}.button-group{a{width:calc(50%-0.5px);文本对齐:居中;字体大小:17px;行高:43px;颜色:蓝色;}.max-width{width:100%!important;;}}}}{{message}}