bug
jiangping
2023-11-07 64b432916af9c9218ab3f3eca614e26c542142ae
minipro_standard/uni_modules/uview-ui/components/u-toast/u-toast.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,291 @@
<template>
   <view class="u-toast">
      <u-overlay
         :show="isShow"
         :custom-style="overlayStyle"
      >
         <view
            class="u-toast__content"
            :style="[contentStyle]"
            :class="['u-type-' + tmpConfig.type, (tmpConfig.type === 'loading' || tmpConfig.loading) ?  'u-toast__content--loading' : '']"
         >
            <u-loading-icon
               v-if="tmpConfig.type === 'loading'"
               mode="circle"
               color="rgb(255, 255, 255)"
               inactiveColor="rgb(120, 120, 120)"
               size="25"
            ></u-loading-icon>
            <u-icon
               v-else-if="tmpConfig.type !== 'defalut' && iconName"
               :name="iconName"
               size="17"
               :color="tmpConfig.type"
               :customStyle="iconStyle"
            ></u-icon>
            <u-gap
               v-if="tmpConfig.type === 'loading' || tmpConfig.loading"
               height="12"
               bgColor="transparent"
            ></u-gap>
            <text
               class="u-toast__content__text"
               :class="['u-toast__content__text--' + tmpConfig.type]"
               style="max-width: 400rpx;"
            >{{ tmpConfig.message }}</text>
         </view>
      </u-overlay>
   </view>
</template>
<script>
   /**
    * toast æ¶ˆæ¯æç¤º
    * @description æ­¤ç»„件表现形式类似uni的uni.showToastAPI,但也有不同的地方。
    * @tutorial https://www.uviewui.com/components/toast.html
    * @property {String | Number}   zIndex      toast展示时的zIndex值 (默认 10090 )
    * @property {Boolean}         loading      æ˜¯å¦åŠ è½½ä¸­ ï¼ˆé»˜è®¤ false ï¼‰
    * @property {String | Number}   message      æ˜¾ç¤ºçš„æ–‡å­—内容
    * @property {String}         icon      å›¾æ ‡ï¼Œæˆ–者绝对路径的图片
    * @property {String}         type      ä¸»é¢˜ç±»åž‹ ï¼ˆé»˜è®¤ default)
    * @property {Boolean}         show      æ˜¯å¦æ˜¾ç¤ºè¯¥ç»„ä»¶ ï¼ˆé»˜è®¤ false)
    * @property {Boolean}         overlay      æ˜¯å¦æ˜¾ç¤ºé€æ˜Žé®ç½©ï¼Œé˜²æ­¢ç‚¹å‡»ç©¿é€ ï¼ˆé»˜è®¤ false ï¼‰
    * @property {String}         position   ä½ç½® ï¼ˆé»˜è®¤ 'center' ï¼‰
    * @property {Object}         params      è·³è½¬çš„参数
    * @property {String | Number}  duration   å±•示时间,单位ms ï¼ˆé»˜è®¤ 2000 ï¼‰
    * @property {Boolean}         isTab      æ˜¯å¦è¿”回的为tab页面 ï¼ˆé»˜è®¤ false ï¼‰
    * @property {String}         url         toast消失后是否跳转页面,有则跳转,优先级高于back参数
    * @property {Function}         complete   æ‰§è¡Œå®ŒåŽçš„回调函数
    * @property {Boolean}         back      ç»“束toast是否自动返回上一页 ï¼ˆé»˜è®¤ false ï¼‰
    * @property {Object}         customStyle   ç»„件的样式,对象形式
    * @event {Function} show æ˜¾ç¤ºtoast,如需一进入页面就显示toast,请在onReady生命周期调用
    * @example <u-toast ref="uToast" />
    */
   export default {
      name: 'u-toast',
      mixins: [uni.$u.mpMixin, uni.$u.mixin],
      data() {
         return {
            isShow: false,
            timer: null, // å®šæ—¶å™¨
            config: {
               message: '', // æ˜¾ç¤ºæ–‡æœ¬
               type: '', // ä¸»é¢˜ç±»åž‹ï¼Œprimary,success,error,warning,black
               duration: 2000, // æ˜¾ç¤ºçš„æ—¶é—´ï¼Œæ¯«ç§’
               icon: true, // æ˜¾ç¤ºçš„图标
               position: 'center', // toast出现的位置
               complete: null, // æ‰§è¡Œå®ŒåŽçš„回调函数
               overlay: false, // æ˜¯å¦é˜²æ­¢è§¦æ‘¸ç©¿é€
               loading: false, // æ˜¯å¦åŠ è½½ä¸­çŠ¶æ€
            },
            tmpConfig: {}, // å°†ç”¨æˆ·é…ç½®å’Œå†…置配置合并后的临时配置变量
         }
      },
      computed: {
         iconName() {
            // åªæœ‰ä¸ä¸ºnone,并且type为error|warning|succes|info时候,才显示图标
            if(!this.tmpConfig.icon || this.tmpConfig.icon == 'none') {
               return '';
            }
            if (['error', 'warning', 'success', 'primary'].includes(this.tmpConfig.type)) {
               return uni.$u.type2icon(this.tmpConfig.type)
            } else {
               return ''
            }
         },
         overlayStyle() {
            const style = {
               justifyContent: 'center',
               alignItems: 'center',
               display: 'flex'
            }
            // å°†é®ç½©è®¾ç½®ä¸º100%透明度,避免出现灰色背景
            style.backgroundColor = 'rgba(0, 0, 0, 0)'
            return style
         },
         iconStyle() {
            const style = {}
            // å›¾æ ‡éœ€è¦ä¸€ä¸ªå³è¾¹è·ï¼Œä»¥è·Ÿå³è¾¹çš„æ–‡å­—有隔开的距离
            style.marginRight = '4px'
            // #ifdef APP-NVUE
            // iOSAPP下,图标有1px的向下偏移,这里进行修正
            if (uni.$u.os() === 'ios') {
               style.marginTop = '-1px'
            }
            // #endif
            return style
         },
         loadingIconColor() {
            let color = 'rgb(255, 255, 255)'
            if (['error', 'warning', 'success', 'primary'].includes(this.tmpConfig.type)) {
               // loading-icon组件内部会对color参数进行一个透明度处理,该方法要求传入的颜色值
               // å¿…须为rgb格式的,所以这里做一个处理
               color = uni.$u.hexToRgb(uni.$u.color[this.tmpConfig.type])
            }
            return color
         },
         // å†…容盒子的样式
         contentStyle() {
            const windowHeight = uni.$u.sys().windowHeight, style = {}
            let value = 0
            // æ ¹æ®top和bottom,对Y轴进行窗体高度的百分比偏移
            if(this.tmpConfig.position === 'top') {
               value = - windowHeight * 0.25
            } else if(this.tmpConfig.position === 'bottom') {
               value = windowHeight * 0.25
            }
            style.transform = `translateY(${value}px)`
            return style
         }
      },
      created() {
         // é€šè¿‡ä¸»é¢˜çš„形式调用toast,批量生成方法函数
         ['primary', 'success', 'error', 'warning', 'default', 'loading'].map(item => {
            this[item] = message => this.show({
               type: item,
               message
            })
         })
      },
      methods: {
         // æ˜¾ç¤ºtoast组件,由父组件通过this.$refs.xxx.show(options)形式调用
         show(options) {
            // ä¸å°†ç»“果合并到this.config变量,避免多次调用u-toast,前后的配置造成混乱
            this.tmpConfig = uni.$u.deepMerge(this.config, options)
            // æ¸…除定时器
            this.clearTimer()
            this.isShow = true
            this.timer = setTimeout(() => {
               // å€’计时结束,清除定时器,隐藏toast组件
               this.clearTimer()
               // åˆ¤æ–­æ˜¯å¦å­˜åœ¨callback方法,如果存在就执行
               typeof(this.tmpConfig.complete) === 'function' && this.tmpConfig.complete()
            }, this.tmpConfig.duration)
         },
         // éšè—toast组件,由父组件通过this.$refs.xxx.hide()形式调用
         hide() {
            this.clearTimer()
         },
         clearTimer() {
            this.isShow = false
            // æ¸…除定时器
            clearTimeout(this.timer)
            this.timer = null
         }
      },
      beforeDestroy() {
         this.clearTimer()
      }
   }
</script>
<style lang="scss" scoped>
   @import "../../libs/css/components.scss";
   $u-toast-color:#fff !default;
   $u-toast-border-radius:4px !default;
   $u-toast-border-background-color:#585858 !default;
   $u-toast-border-font-size:14px !default;
   $u-toast-border-padding:12px 20px !default;
   $u-toast-loading-border-padding: 20px 20px !default;
   $u-toast-content-text-color:#fff !default;
   $u-toast-content-text-font-size:15px !default;
   $u-toast-u-icon:10rpx !default;
   $u-toast-u-type-primary-color:$u-primary !default;
   $u-toast-u-type-primary-background-color:#ecf5ff !default;
   $u-toast-u-type-primary-border-color:rgb(215, 234, 254) !default;
   $u-toast-u-type-primary-border-width:1px !default;
   $u-toast-u-type-success-color: $u-success !default;
   $u-toast-u-type-success-background-color: #dbf1e1 !default;
   $u-toast-u-type-success-border-color: #BEF5C8 !default;
   $u-toast-u-type-success-border-width: 1px !default;
   $u-toast-u-type-error-color:$u-error !default;
   $u-toast-u-type-error-background-color:#fef0f0 !default;
   $u-toast-u-type-error-border-color:#fde2e2 !default;
   $u-toast-u-type-error-border-width: 1px !default;
   $u-toast-u-type-warning-color:$u-warning !default;
   $u-toast-u-type-warning-background-color:#fdf6ec !default;
   $u-toast-u-type-warning-border-color:#faecd8 !default;
   $u-toast-u-type-warning-border-width: 1px !default;
   $u-toast-u-type-default-color:#fff !default;
   $u-toast-u-type-default-background-color:#585858 !default;
   .u-toast {
      &__content {
         @include flex;
         padding: $u-toast-border-padding;
         border-radius: $u-toast-border-radius;
         background-color: $u-toast-border-background-color;
         color: $u-toast-color;
         align-items: center;
         /* #ifndef APP-NVUE */
         max-width: 600rpx;
         /* #endif */
         position: relative;
         &--loading {
            flex-direction: column;
            padding: $u-toast-loading-border-padding;
         }
         &__text {
            color: $u-toast-content-text-color;
            font-size: $u-toast-content-text-font-size;
            line-height: $u-toast-content-text-font-size;
            &--default {
               color: $u-toast-content-text-color;
            }
            &--error {
               color: $u-error;
            }
            &--primary {
               color: $u-primary;
            }
            &--success {
               color: $u-success;
            }
            &--warning {
               color: $u-warning;
            }
         }
      }
   }
   .u-type-primary {
      color: $u-toast-u-type-primary-color;
      background-color: $u-toast-u-type-primary-background-color;
      border-color: $u-toast-u-type-primary-border-color;
      border-width: $u-toast-u-type-primary-border-width;
   }
   .u-type-success {
      color: $u-toast-u-type-success-color;
      background-color: $u-toast-u-type-success-background-color;
      border-color: $u-toast-u-type-success-border-color;
      border-width: 1px;
   }
   .u-type-error {
      color: $u-toast-u-type-error-color;
      background-color: $u-toast-u-type-error-background-color;
      border-color: $u-toast-u-type-error-border-color;
      border-width: $u-toast-u-type-error-border-width;
   }
   .u-type-warning {
      color: $u-toast-u-type-warning-color;
      background-color: $u-toast-u-type-warning-background-color;
      border-color: $u-toast-u-type-warning-border-color;
      border-width: 1px;
   }
   .u-type-default {
      color: $u-toast-u-type-default-color;
      background-color: $u-toast-u-type-default-background-color;
   }
</style>