自制消息提示组件
一. VUE文件
主要是通过v-if来增加主键的功能
<template>
<div
class="zoehis_zoeMessage"
ref="dialog"
:class="['customClass',closed ? 'zoehis_zoeMessage_close_animation' : 'zoehis_zoeMessage_animation']"
:style="positionStyle"
v-show="visible"
@mouseenter="clearTimer"
@mouseleave="startTimer"
>
<i v-if="iconClass" class="zoehis_icon zoeIconfont" :class="iconClass"></i>
<i v-else class="zoehis_icon zoeIconfont" :class="[iconTypeClass]"></i>
<div class="zoehis_zoeMessage_message">
<p class="zoehis_zoeMessage_message" v-html="message"></p>
</div>
<i v-if="showClose" class="zoehis_icon_close zoeIconfont z_wrong_normal" @click="close"></i>
</div>
</template>
<script type="text/babel">
import { isNull } from "../../../src/utils/util.js";
let iconTypeMap = {
success: "success_icon z_right_normal",
error: "error_icon z_wrong_normal",
info: "info_icon jingshi",
warn: "warn_icon jingshi"
};
export default {
data() {
return {
message: "", // 消息文字
type: "success", // 类别,success/warning/info/error
customClass: "", // 自定义类名
duration: 2000, // 显示时间, 毫秒。默认2000ms
timer: null, // 内部计时器
visible: false, // 显示消息弹窗
closed: false, // 关闭消息弹窗
verticalOffset: 20,// 内部默认zoeMessage距离窗口顶部的偏移量,默认为20px
onClose: null, // 关闭时的回调函数, 参数为被关闭的 zoeMessage 实例
iconType: '', // 配置提示信息图标,不配置保留原始图标样子
iconClass: '', // 自定义图标的类名,会覆盖 type
spacingOffset: 16, // 配置消息提示框间隔,默认为16px
showClose: false, // 展示关闭按钮
};
},
computed: {
// 获取图标样式,支持自己混合组合
iconTypeClass() {
let iconType = this.type;
if (!isNull(this.iconType) && iconTypeMap[this.iconType]) {
iconType = this.iconType;
}
return iconTypeMap[iconType];
},
positionStyle() {
return {
'top': `${ this.verticalOffset }px`
};
}
},
mounted() {
this.startTimer()
},
watch: {
closed(newVal) {
if (newVal) {
setTimeout(() => {
this.visible = false;
this.handleAfterLeave()
},500)
}
}
},
methods: {
clearTimer() {
clearTimeout(this.timer);
},
startTimer() {
if (this.duration > 0) {
this.timer = setTimeout(() => {
if (!this.closed) {
this.close()
}
}, this.duration);
}
},
close() {
this.closed = true;
if (typeof this.onClose === 'function') {
this.onClose(this);
}
},
// 销毁
handleAfterLeave() {
this.$destroy(true);
this.$el.parentNode.removeChild(this.$el);
},
},
};
</script>
二. JS文件
定义一个实例,并绑定到dom上,然后设置其参数和方法,最后导出
import Vue from 'vue';
import zoeMessageVue from './zoeMessage.vue';
const MessageConstructor = Vue.extend(zoeMessageVue);
let instance;
let instances = [];
let seed = 1;
const zoeMessage = function(options) {
if (Vue.prototype.$isServer) return;
options = options || {};
if (typeof options === 'string') {
options = {
message: options
};
}
let userOnClose = options.onClose;
let id = 'message_' + seed++;
options.onClose = function() {
zoeMessage.close(id, userOnClose);
};
instance = new MessageConstructor({
data: options
});
instance.id = id;
instance.$mount();
document.body.appendChild(instance.$el);
let verticalOffset = options.offset || 20;
// 消息超过2个时,计算新的verticalOffset
instances.forEach(item => {
verticalOffset += item.$el.offsetHeight + item.spacingOffset;
});
instance.verticalOffset = verticalOffset;
instance.visible = true;
instances.push(instance);
return instance;
};
['success', 'warn', 'info', 'error'].forEach(type => {
zoeMessage[type] = (options) => {
return zoeMessage({
type,
message: options
});
};
});
zoeMessage.close = function(id, userOnClose) {
let len = instances.length;
let index = -1;
let removedHeight, removeSpacingdHeight;
for (let i = 0; i < len; i++) {
if (id === instances[i].id) {
removedHeight = instances[i].$el.offsetHeight;
removeSpacingdHeight = instances[i].spacingOffset;
index = i;
if (typeof userOnClose === 'function') {
userOnClose(instances[i]);
}
instances.splice(i, 1);
break;
}
}
if (len <= 1 || index === -1 || index > instances.length - 1) return;
for (let i = index; i < len - 1; i++) {
let dom = instances[i].$el;
dom.style['top'] =
parseInt(dom.style['top'], 10) - removedHeight - removeSpacingdHeight + 'px';
}
};
// 关闭全部消息
zoeMessage.closeAll = function() {
for (let i = instances.length - 1; i >= 0; i--) {
instances[i].close();
}
};
export default zoeMessage;
export { zoeMessage };
三. index.js文件
导出组件
/**
* Created by chenzhilin on 2021/11/23.
*/
import zoeMessage from './src/zoeMessage.js';
export default zoeMessage;
四. scss文件
通过变量设置其各自的样式
.zoehis_zoeMessage{
outline: none;
position: fixed;
top: 20px;
left: 50%;
margin: 0;
z-index: 10000;
width: max-content;
height: max-content;
min-width: 300px;
max-width: 60%;
min-height: 60px;
max-height: 10%;
padding: 0 20px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0px 0px 5px $MAINBORDERLINES;
font-family: $FONTNORMAL;
background-color: $MAINBG;
transform: translateX(-50%);
overflow: hidden;
text-overflow:ellipsis;
.zoehis_icon{
font-size: 26px;
&.success_icon{color: #21b86c;}
&.warn_icon{color: $ERRORCOLOR;}
&.error_icon{color: $MAINURGENT;}
&.info_icon{color: $SCROLLBARHOVE;}
&+.zoehis_zoeMessage_message{ padding-left: 11px;}
}
.zoehis_icon_close{
font-size: 26px;
color: $MAINBG;
padding-left: 11px;
text-shadow: 0px 0px 5px $MAINBORDERLINES;
&:focus {
color: $FONTFOCUS;
}
&:hover {
color: $FONTFOCUS;
}
}
.zoehis_zoeMessage_message{
font-size: $FONTMAINS;
color: #545454;
word-wrap: break-word;
word-break: break-all;
overflow: hidden;
text-overflow:ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3; //显示内容的行数; 要显示几行数字为几即可!
-webkit-box-orient: vertical;
&:hover {
text-overflow:inherit;
overflow: auto;
white-space: pre-line; /*合并空白符序列,但是保留换行符。*/
}
}
}
.zoehis_zoeMessage_animation {
-webkit-animation: zoehis_zoeMessage_animation 500ms linear both;
animation: zoehis_zoeMessage_animation 500ms linear both;
}
@keyframes zoehis_zoeMessage_animation {
0% {
opacity: 0.2;
transform: translate(-50%, -100%);
}
100% {
opacity: 1;
transform: translate(-50%, 0);
}
}
.zoehis_zoeMessage_close_animation {
-webkit-animation: zoehis_zoeMessage_close_animation 500ms linear both;
animation: zoehis_zoeMessage_close_animation 500ms linear both;
}
@keyframes zoehis_zoeMessage_close_animation {
0% {
opacity: 1;
transform: translate(-50%, 0);
}
100% {
opacity: 0.3;
transform: translate(-50%, -100%);
}
}
.zoehis_zoeMessage_animation,
.zoehis_zoeMessage_close_animation {
transition: top 1s cubic-bezier(0.6, 0.04, 0.98, 0.335), opacity 1s;
}
本文来自博客园,作者:暗鸦08,转载请注明原文链接:https://www.cnblogs.com/DarkCrow/p/15594365.html

浙公网安备 33010602011771号