前几天想了解vue如何写弹窗组件
有以下两种可取的写法:
1.状态管理 如果弹窗组件放在根组件,使用vuex来管理组件的show和hide。放在组件内,通过增加v-show或v-if来控制,可结合slot,定义不同需求的弹窗
2.事件管理 注册一个全局事件来打开弹窗,传入需展示的文字和相关的逻辑控制,可结合promise,实现异步
觉得对用像/confirm/ie和propmt这类弹窗,还是事件驱动的好。最好就是能使用promise回调。
于是手痒就写了一个。下面是代码。
propmt.js
import Vue from 'vue'
import promptComponent from './prompt.vue' // 引入弹窗的vue文件
const promptConstructor = Vue.extend(promptComponent); // 注册组件
let instance = new promptConstructor().$mount(''); // 获得组件的实例
document.body.appendChild(instance.$el); // 将组件的element插入到body中
const alert = (text,okText)=>{
if(instance.show === true) { //防止多次触发
return;
}
// 为弹窗数据赋值
instance.show = true;
instance.isalert = true;
instance.okText = okText||'确定';
instance.message = text;
//返回一个promise对象,并为按钮添加事件监听
return new Promise(function(resolve,reject) {
instance.$refs.okBtn.addEventListener('click',function() {
instance.show = false;
resolve(true);
})
})
};
const Confirm = (text,okText,cancelText)=>{
if(instance.show === true) {
return;
}
instance.show = true;
instance.okText = okText||'确定';
instance.cancelText = cancelText||'取消';
instance.message = text;
return new Promise(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);
})
})
};
const prompt = (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 || '';
return new Promise(function(resolve,reject) {
instance.$refs.okBtn.addEventListener('click',function() {
instance.show = false;
resolve(instance.inputValue);
})
})
};
export {alert,/confirm/i,prompt}
prompt.vue
./confirm/i-enter-active { transition: all .2s; } ./confirm/i-leave-active { transition: opacity .2s; } ./confirm/i-leave-to { opacity: 0; } ./confirm/i-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 .1s linear; transition: opacity .1s linear; 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: 20px auto 0 auto; vertical-align: middle; } &::after { content: ''; height: 100%; } } .prompt { margin: 20px 0; width: 100%; p { margin: 5px auto; font-size: 17px; line-height: 24px; } input { margin: 5px auto; border: 1px solid #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}}
{{cancelText}} {{okText}}
main.js
import {alert,prompt,/confirm/i} from '../lib/components/prompt/prompt.js'
Vue.prototype.alert = function(text,okText) {
return alert(text,okText)
};
Vue.prototype.Confirm = function(text,okText,cancelText) {
return Confirm(text,okText,cancelText)
};
Vue.prototype.prompt = function(text,okText,inputType, defaultValue) {
return prompt(text,okText,inputType, defaultValue)
};
component.vue:
inputName() {
this.prompt('请输入名称','确认','text').then(res =>{
// do something use res
});
},
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。



