| <template> | 
|   <view v-if="visible"> | 
|     <view | 
|       class="tn-toast-class tn-toast" | 
|       :class="[toastClass]" | 
|       :style="[toastStyle]" | 
|     > | 
|       <image v-if="image" :src="image" class="tn-toast__img" :class="{'tn-margin-bottom-sm': title || content}"></image> | 
|       <view v-if="icon" class="tn-toast__icon"> | 
|         <view :class="['tn-icon-' + icon]"></view> | 
|       </view> | 
|       <view | 
|         v-if="title" | 
|         class="tn-toast__text" | 
|         :class="[haveIcon || haveContent ? '' : 'tn-toast--unicon']" | 
|       >{{ title }}</view> | 
|       <view | 
|         v-if="haveContent" | 
|         class="tn-toast__text tn-toast__content" | 
|       >{{ content }}</view> | 
|     </view> | 
|      | 
|     <view class="tn-toast__mask" :class="[visible ? 'tn-toast__mask--show' : '']" :style="[maskStyle]"></view> | 
|   </view> | 
| </template> | 
|   | 
| <script> | 
|    | 
|   export default { | 
|     name: 'tn-toast', | 
|     props: { | 
|       // 层级 | 
|       zIndex: { | 
|         type: Number, | 
|         default: 0 | 
|       } | 
|     }, | 
|     computed: { | 
|       toastClass() { | 
|         let clazz = '' | 
|         if (this.visible) { | 
|           clazz += ' tn-toast--show' | 
|         } | 
|          | 
|         if (this.content) { | 
|           clazz += ' tn-toast--padding' | 
|         } | 
|         if (this.icon || this.image) { | 
|           clazz += ' tn-toast--unicon' | 
|         } | 
|          | 
|         return clazz | 
|       }, | 
|       toastStyle() { | 
|         let style = {} | 
|         style.width = 'auto' | 
|         if (this.icon || this.image) { | 
|           // style.width = this.content ? '420rpx' : '360rpx' | 
|         } | 
|   | 
|         style.zIndex = this.zIndex ? this.zIndex : this.$t.zIndex.toast | 
|          | 
|         return style | 
|       }, | 
|       maskStyle() { | 
|         let style = {} | 
|         const zIndex = this.zIndex ? this.zIndex : this.$t.zIndex.toast | 
|         style.zIndex = zIndex - 1 | 
|         return style | 
|       }, | 
|       haveIcon() { | 
|         return this.icon || this.image | 
|       }, | 
|       haveContent() { | 
|         return this.content | 
|       } | 
|     }, | 
|     data() { | 
|       return { | 
|         // 自动关闭定时器 | 
|         timer: null, | 
|         // 是否显示 | 
|         visible: false, | 
|         // 显示的标题 | 
|         title: '操作成功', | 
|         // 显示的内容 | 
|         content: "", | 
|         // 是否显示icon (icon库的图标) | 
|         icon: '', | 
|         // 是否显示图片 (图片地址) | 
|         image: '' | 
|       } | 
|     }, | 
|     methods: { | 
|       // 显示弹框 | 
|       show(options = {}) { | 
|         const { | 
|           duration = 2000, | 
|           title = '', | 
|           content = '', | 
|           icon = '', | 
|           image = '' | 
|         } = options | 
|         if (this.timer !== null ){ | 
|           clearTimeout(this.timer) | 
|         } | 
|         // 如果没有设置任何内容就不弹出 | 
|         if (!icon && !image && !title && !content) { | 
|           this._clearOptions() | 
|           this.$emit('closed') | 
|           return | 
|         } | 
|          | 
|         this.visible = true | 
|         this.title = title | 
|         this.content = content | 
|         this.icon = icon | 
|         if (!icon) { | 
|           this.image = image | 
|         } | 
|          | 
|         this.timer = setTimeout(() => { | 
|           this.visible = false | 
|           clearTimeout(this.timer) | 
|           this.timer = null | 
|           this._clearOptions() | 
|           this.$emit('closed') | 
|         }, duration) | 
|       }, | 
|        | 
|        | 
|       // 清除传递的参数 | 
|       _clearOptions() { | 
|         this.title = '' | 
|         this.content = '' | 
|         this.icon = '' | 
|         this.image = '' | 
|       } | 
|     } | 
|   } | 
| </script> | 
|   | 
| <style lang="scss" scoped> | 
|    | 
|   .tn-toast { | 
|     height: auto; | 
|     background-color: rgba(0, 0, 0, 0.4); | 
|     border-radius: 10rpx; | 
|     opacity: 0; | 
|     position: fixed; | 
|     left: 50%; | 
|     top: 48%; | 
|     transform: translate(-50%, -50%); | 
|     transition: 0.3 ease-in-out; | 
|     transition-property: opacity, visibility; | 
|     display: flex; | 
|     align-items: center; | 
|     flex-direction: column; | 
|     padding: 20rpx 20rpx 20rpx 20rpx; | 
|     box-sizing: border-box; | 
|      | 
|     &--show { | 
|       opacity: 1; | 
|        | 
|       &.tn-toast--padding { | 
|         padding-top: 50rpx !important; | 
|         padding-bottom: 50rpx !important; | 
|       } | 
|        | 
|       &.tn-toast--unicon { | 
|         padding: 20rpx 20rpx 20rpx 20rpx !important; | 
|       } | 
|     } | 
|      | 
|     &__img { | 
|       width: 120rpx; | 
|       height: 120rpx; | 
|       display: block; | 
|     } | 
|      | 
|     &__text { | 
|       font-size: 28rpx; | 
|       line-height: 28rpx; | 
|       color: #ffffff; | 
|       text-align: center; | 
|     } | 
|      | 
|     &__icon { | 
|       color: #FFFFFF; | 
|       font-size: 64rpx; | 
|     } | 
|      | 
|     &__content { | 
|       padding-top: 10rpx; | 
|       font-size: 24rpx !important; | 
|     } | 
|      | 
|     &--unicon { | 
|       padding: 0; | 
|       word-break: break-all; | 
|     } | 
|      | 
|     &--padding { | 
|       padding: 10rpx; | 
|     } | 
|      | 
|     &__mask { | 
|       width: 100%; | 
|       height: 100%; | 
|       position: fixed; | 
|       top: 0; | 
|       left: 0; | 
|       right: 0; | 
|       border: 0; | 
|       background-color: rgba(0, 0, 0, 0); | 
|       transition: 0.3s ease-in-out; | 
|       transition-property: opacity; | 
|       opacity: 0; | 
|        | 
|       &--show { | 
|         height: 100%; | 
|         opacity: 1; | 
|       } | 
|     } | 
|   } | 
|    | 
| </style> |