【新增】封装提示框

This commit is contained in:
2025-11-03 10:39:46 +08:00
parent 3fe027661b
commit c3b3ed3681

View File

@@ -0,0 +1,145 @@
if (!window.Vue) {
const vueScript = document.createElement('script');
vueScript.src = 'https://cdn.jsdelivr.net/npm/vue@3.3.4/dist/vue.global.prod.js';
document.head.appendChild(vueScript);
}
if (!document.querySelector('link[href*="bootstrap-icons"]')) {
const iconLink = document.createElement('link');
iconLink.rel = 'stylesheet';
iconLink.href = 'https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css';
document.head.appendChild(iconLink);
}
const style = document.createElement('style');
style.textContent = `
.h5-message-container {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 9999;
pointer-events: none;
}
.h5-message {
display: flex;
align-items: center;
padding: 14px 24px;
border-radius: 8px;
color: #fff;
font-size: 16px;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);
animation: h5MsgShow 0.4s ease-out forwards;
}
.h5-message.success { background-color: rgba(40, 167, 69, 0.95); }
.h5-message.error { background-color: rgba(220, 53, 69, 0.95); }
.h5-message.warning { background-color: rgba(255, 193, 7, 0.95); color: #333; }
.h5-message.info { background-color: rgba(13, 110, 253, 0.95); }
.h5-message-icon {
margin-right: 10px;
font-size: 20px;
}
@keyframes h5MsgShow {
from { opacity: 0; transform: translate(-50%, -50%) scale(0.9); }
to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
.h5-message.hide { animation: h5MsgHide 0.4s ease-in forwards; }
@keyframes h5MsgHide {
from { opacity: 1; transform: translate(-50%, -50%) scale(1); }
to { opacity: 0; transform: translate(-50%, -50%) scale(0.9); }
}
`;
document.head.appendChild(style);
const messageTemplate = `
<div class="h5-message" :class="[type, { hide: !visible }]">
<i class="h5-message-icon" :class="iconClass"></i>
<span>{{ message }}</span>
</div>
`;
const messageInstances = [];
function showMessage(options) {
if (typeof options === 'string') {
options = { message: options };
}
const config = {
message: '',
type: 'info',
duration: 3000,
...options,
duration: Math.max(1000, options.duration || 3000)
};
const checkVueLoaded = setInterval(() => {
if (window.Vue) {
clearInterval(checkVueLoaded);
const container = document.createElement('div');
container.className = 'h5-message-container';
document.body.appendChild(container);
const app = Vue.createApp({
template: messageTemplate,
data() {
return {
message: config.message,
type: config.type,
visible: true
};
},
computed: {
iconClass() {
const icons = {
success: 'bi bi-check-circle',
error: 'bi bi-exclamation-circle',
warning: 'bi bi-exclamation-triangle',
info: 'bi bi-info-circle'
};
return icons[this.type] || icons.info;
}
},
mounted() {
const showTimer = setTimeout(() => {
this.visible = false;
const hideTimer = setTimeout(() => {
const index = messageInstances.indexOf(app);
if (index > -1) {
messageInstances.splice(index, 1);
}
app.unmount(container);
document.body.removeChild(container);
clearTimeout(hideTimer);
}, 400);
clearTimeout(showTimer);
}, config.duration);
}
});
const instance = app.mount(container);
messageInstances.push(instance);
}
}, 50);
setTimeout(() => {
clearInterval(checkVueLoaded);
if (!window.Vue) {
alert(config.message);
}
}, 1000);
}
window.$message = showMessage;
['success', 'error', 'warning', 'info'].forEach(type => {
window.$message[type] = (message, duration) => {
window.$message({
message,
type,
// 确保时长有效用户未传则用默认3秒
duration: duration ? Math.max(1000, duration) : 500
});
};
});