You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

170 lines
3.2 KiB

<template>
<transition name="fade">
<div v-if="visible" class="custom-message" :class="[type, position]">
<img v-if="showImage" :src="imageUrl" class="message-image" />
<i v-else :class="iconClass"></i>
<span class="message-content">{{ message }}</span>
</div>
</transition>
</template>
<script>
export default {
name: 'CustomMessage',
props: {
type: {
type: String,
default: 'info',
validator: value => ['success', 'warning', 'error', 'info'].includes(value)
},
message: {
type: String,
required: true
},
duration: {
type: Number,
default: 3000
},
position: {
type: String,
default: 'top-center',
validator: value => ['top-center', 'top-right', 'top-left', 'bottom-center', 'bottom-right', 'bottom-left'].includes(value)
},
showImage: {
type: Boolean,
default: false
},
imageUrl: {
type: String,
default: ''
},
iconClass: {
type: String,
default: ''
}
},
data() {
return {
visible: false
}
},
mounted() {
this.visible = true
this.startTimer()
},
methods: {
startTimer() {
if (this.duration > 0) {
setTimeout(() => {
this.close()
}, this.duration)
}
},
close() {
this.visible = false
setTimeout(() => {
this.$destroy()
this.$el.parentNode.removeChild(this.$el)
}, 300)
}
}
}
</script>
<style scoped>
.custom-message {
position: fixed;
z-index: 9999;
display: flex;
align-items: center;
padding: 14px 21px;
transition: all 0.3s;
font-size: 14px;
font-weight: normal;
line-height: normal;
letter-spacing: 0.08em;
color: #626573;
border-radius: 4px;
background: #FFFFFF;
/* 阴影/低阴影 */
box-shadow: 0px 3px 8px 0px rgba(0, 0, 0, 0.16);
}
/* 位置样式 */
.top-center {
top: 20px;
left: 50%;
transform: translateX(-50%);
}
.top-right {
top: 20px;
right: 20px;
}
.top-left {
top: 20px;
left: 20px;
}
.bottom-center {
bottom: 20px;
left: 50%;
transform: translateX(-50%);
}
.bottom-right {
bottom: 20px;
right: 20px;
}
.bottom-left {
bottom: 20px;
left: 20px;
}
/* 类型样式 */
/* .success {
background-color: #f6ffed;
border: 1px solid #b7eb8f;
color: #52c41a;
}
.info {
background-color: #e6f7ff;
border: 1px solid #91d5ff;
color: #1890ff;
}
.warning {
background-color: #fffbe6;
border: 1px solid #ffe58f;
color: #faad14;
}
.error {
background-color: #fff2f0;
border: 1px solid #ffccc7;
color: #f5222d;
} */
.message-image {
width: 18px;
height: 18px;
margin-right: 10px;
}
/* 动画效果 */
.fade-enter-active, .fade-leave-active {
transition: opacity 0.3s, transform 0.3s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
.fade-enter.top-center, .fade-leave-to.top-center {
transform: translate(-50%, -20px);
}
.fade-enter.top-right, .fade-leave-to.top-right,
.fade-enter.top-left, .fade-leave-to.top-left {
transform: translateY(-20px);
}
.fade-enter.bottom-center, .fade-leave-to.bottom-center {
transform: translate(-50%, 20px);
}
.fade-enter.bottom-right, .fade-leave-to.bottom-right,
.fade-enter.bottom-left, .fade-leave-to.bottom-left {
transform: translateY(20px);
}
</style>