|
|
@@ -1,30 +1,62 @@
|
|
|
<template>
|
|
|
- <div class="message-wrapper">
|
|
|
+ <div class="message-wrapper" :class="type" v-if="show">
|
|
|
<div class="message">
|
|
|
- <div class="icon warning">{{iconfontMap['error']}}</div>
|
|
|
- 自动保存成功!
|
|
|
+ <span class="icon warning">{{iconMap[type] ? iconMap[type] : iconMap['info']}}</span>
|
|
|
+ <span class="message-content">{{ message }}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import iconfontMap from '@/utils/iconfont-map'
|
|
|
+import iconMap from '@/utils/icon-map'
|
|
|
+import { mapState } from 'vuex'
|
|
|
+import { USE_MESSAGE } from '@/store/types/message-types'
|
|
|
|
|
|
export default {
|
|
|
data () {
|
|
|
return {
|
|
|
- iconfontMap: iconfontMap
|
|
|
+ iconMap: iconMap,
|
|
|
+ show: false
|
|
|
}
|
|
|
},
|
|
|
- computed: {}
|
|
|
+ computed: {
|
|
|
+ ...mapState({
|
|
|
+ message: state => state.message.message,
|
|
|
+ type: state => state.message.type,
|
|
|
+ duration: state => state.message.duration
|
|
|
+ })
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ message (newMessage) {
|
|
|
+ if (newMessage) {
|
|
|
+ this.show = false
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.show = true
|
|
|
+ setTimeout(() => {
|
|
|
+ this.show = false
|
|
|
+ this.$store.commit(USE_MESSAGE)
|
|
|
+ }, 5000)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
+@import "~@/style/theme.scss";
|
|
|
+
|
|
|
.message-wrapper {
|
|
|
+ width: 100%;
|
|
|
+ opacity: 0;
|
|
|
display: flex;
|
|
|
justify-content: center;
|
|
|
+ position: fixed;
|
|
|
+ top: 20px;
|
|
|
+ margin: 0 auto;
|
|
|
+ z-index: 2;
|
|
|
+ animation: show 5s ease-out;
|
|
|
}
|
|
|
|
|
|
.icon {
|
|
|
@@ -35,24 +67,54 @@ export default {
|
|
|
user-select: none;
|
|
|
}
|
|
|
|
|
|
-.warning {
|
|
|
- color: darkorange;
|
|
|
+.message-content {
|
|
|
+ padding: 0 12px 0 4px
|
|
|
}
|
|
|
|
|
|
.message {
|
|
|
- color: #2a3a4a;
|
|
|
+ color: #6a7a8a;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
- position: fixed;
|
|
|
- top: 20px;
|
|
|
- z-index: 2;
|
|
|
font-size: 16px;
|
|
|
font-weight: bold;
|
|
|
margin: 0 auto;
|
|
|
padding: 8px 10px;
|
|
|
border-radius: 100px;
|
|
|
backdrop-filter: saturate(180%) blur(20px);
|
|
|
- background: rgba(230, 230, 230, 0.6);
|
|
|
+ background: $theme-blue-transparent;
|
|
|
+}
|
|
|
+
|
|
|
+.error {
|
|
|
+ .message {
|
|
|
+ color: $theme-red;
|
|
|
+ background: $theme-red-transparent;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.success {
|
|
|
+ .message {
|
|
|
+ color: $theme-green;
|
|
|
+ background: $theme-green-transparent;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+@keyframes show {
|
|
|
+ 0% {
|
|
|
+ opacity: 0;
|
|
|
+ transform: translateY(-100px);
|
|
|
+ }
|
|
|
+ 12% {
|
|
|
+ opacity: 1;
|
|
|
+ transform: translateY(0);
|
|
|
+ }
|
|
|
+ 95% {
|
|
|
+ opacity: 1;
|
|
|
+ transform: translateY(0);
|
|
|
+ }
|
|
|
+ 100% {
|
|
|
+ opacity: 0;
|
|
|
+ transform: translateY(-100px);
|
|
|
+ }
|
|
|
}
|
|
|
</style>
|