u-notify.vue 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. <template>
  2. <u-transition mode="slide-down" :customStyle="containerStyle" :show="open">
  3. <view class="u-notify" :class="[`u-notify--${tmpConfig.type}`]" :style="[backgroundColor, $u.addStyle(customStyle)]">
  4. <u-status-bar v-if="tmpConfig.safeAreaInsetTop"></u-status-bar>
  5. <view class="u-notify__warpper">
  6. <slot name="icon">
  7. <u-icon
  8. v-if="['success', 'warning', 'error'].includes(tmpConfig.type)"
  9. :name="tmpConfig.icon"
  10. :color="tmpConfig.color"
  11. :size="1.3 * tmpConfig.fontSize"
  12. :customStyle="{ marginRight: '4px' }"
  13. ></u-icon>
  14. </slot>
  15. <text
  16. class="u-notify__warpper__text"
  17. :style="{
  18. fontSize: $u.addUnit(tmpConfig.fontSize),
  19. color: tmpConfig.color
  20. }"
  21. >
  22. {{ tmpConfig.message }}
  23. </text>
  24. </view>
  25. </view>
  26. </u-transition>
  27. </template>
  28. <script>
  29. import props from './props.js';
  30. /**
  31. * notify 顶部提示
  32. * @description 该组件一般用于页面顶部向下滑出一个提示,尔后自动收起的场景
  33. * @tutorial
  34. * @property {String | Number} top 到顶部的距离 ( 默认 0 )
  35. * @property {String} type 主题,primary,success,warning,error ( 默认 'primary' )
  36. * @property {String} color 字体颜色 ( 默认 '#ffffff' )
  37. * @property {String} bgColor 背景颜色
  38. * @property {String} message 展示的文字内容
  39. * @property {String | Number} duration 展示时长,为0时不消失,单位ms ( 默认 3000 )
  40. * @property {String | Number} fontSize 字体大小 ( 默认 15 )
  41. * @property {Boolean} safeAreaInsetTop 是否留出顶部安全距离(状态栏高度) ( 默认 false )
  42. * @property {Object} customStyle 组件的样式,对象形式
  43. * @event {Function} open 开启组件时调用的函数
  44. * @event {Function} close 关闭组件式调用的函数
  45. * @example <u-notify message="Hi uView"></u-notify>
  46. */
  47. export default {
  48. name: 'u-notify',
  49. mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
  50. data() {
  51. return {
  52. // 是否展示组件
  53. open: false,
  54. timer: null,
  55. config: {
  56. // 到顶部的距离
  57. top: uni.$u.props.notify.top,
  58. // type主题,primary,success,warning,error
  59. type: uni.$u.props.notify.type,
  60. // 字体颜色
  61. color: uni.$u.props.notify.color,
  62. // 背景颜色
  63. bgColor: uni.$u.props.notify.bgColor,
  64. // 展示的文字内容
  65. message: uni.$u.props.notify.message,
  66. // 展示时长,为0时不消失,单位ms
  67. duration: uni.$u.props.notify.duration,
  68. // 字体大小
  69. fontSize: uni.$u.props.notify.fontSize,
  70. // 是否留出顶部安全距离(状态栏高度)
  71. safeAreaInsetTop: uni.$u.props.notify.safeAreaInsetTop
  72. },
  73. // 合并后的配置,避免多次调用组件后,可能会复用之前使用的配置参数
  74. tmpConfig: {}
  75. };
  76. },
  77. computed: {
  78. containerStyle() {
  79. let top = 0;
  80. if (this.tmpConfig.top === 0) {
  81. // #ifdef H5
  82. // H5端,导航栏为普通元素,需要将组件移动到导航栏的下边沿
  83. // H5的导航栏高度为44px
  84. top = 44;
  85. // #endif
  86. }
  87. const style = {
  88. top: uni.$u.addUnit(this.tmpConfig.top === 0 ? top : this.tmpConfig.top),
  89. // 因为组件底层为u-transition组件,必须将其设置为fixed定位
  90. // 让其出现在导航栏底部
  91. position: 'fixed',
  92. left: 0,
  93. right: 0,
  94. zIndex: 10076
  95. };
  96. return style;
  97. },
  98. // 组件背景颜色
  99. backgroundColor() {
  100. const style = {};
  101. if (this.tmpConfig.bgColor) {
  102. style.backgroundColor = this.tmpConfig.bgColor;
  103. }
  104. return style;
  105. },
  106. // 默认主题下的图标
  107. icon() {
  108. let icon;
  109. if (this.tmpConfig.type === 'success') {
  110. icon = 'checkmark-circle';
  111. } else if (this.tmpConfig.type === 'error') {
  112. icon = 'close-circle';
  113. } else if (this.tmpConfig.type === 'warning') {
  114. icon = 'error-circle';
  115. }
  116. return icon;
  117. }
  118. },
  119. created() {
  120. // 通过主题的形式调用toast,批量生成方法函数
  121. ['primary', 'success', 'error', 'warning'].map(item => {
  122. this[item] = message =>
  123. this.show({
  124. type: item,
  125. message
  126. });
  127. });
  128. },
  129. methods: {
  130. show(options) {
  131. // 不将结果合并到this.config变量,避免多次调用u-toast,前后的配置造成混乱
  132. this.tmpConfig = uni.$u.deepMerge(this.config, options);
  133. // 任何定时器初始化之前,都要执行清除操作,否则可能会造成混乱
  134. this.clearTimer();
  135. this.open = true;
  136. if (this.tmpConfig.duration > 0) {
  137. this.timer = setTimeout(() => {
  138. this.open = false;
  139. // 倒计时结束,清除定时器,隐藏toast组件
  140. this.clearTimer();
  141. // 判断是否存在callback方法,如果存在就执行
  142. typeof this.tmpConfig.complete === 'function' && this.tmpConfig.complete();
  143. }, this.tmpConfig.duration);
  144. }
  145. },
  146. // 关闭notify
  147. close() {
  148. this.clearTimer();
  149. },
  150. clearTimer() {
  151. this.open = false;
  152. // 清除定时器
  153. clearTimeout(this.timer);
  154. this.timer = null;
  155. }
  156. },
  157. beforeDestroy() {
  158. this.clearTimer();
  159. }
  160. };
  161. </script>
  162. <style lang="scss" scoped>
  163. @import '../../libs/css/components.scss';
  164. $u-notify-padding: 8px 10px !default;
  165. $u-notify-text-font-size: 15px !default;
  166. $u-notify-primary-bgColor: $u-primary !default;
  167. $u-notify-success-bgColor: $u-success !default;
  168. $u-notify-error-bgColor: $u-error !default;
  169. $u-notify-warning-bgColor: $u-warning !default;
  170. .u-notify {
  171. padding: $u-notify-padding;
  172. width: 35%;
  173. margin: 0 auto;
  174. border-radius: 20px;
  175. margin-top: 55px;
  176. box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.3);
  177. @media screen and(min-width:$min-width) {
  178. width: 15%;
  179. }
  180. &__warpper {
  181. @include flex;
  182. align-items: center;
  183. text-align: center;
  184. justify-content: center;
  185. &__text {
  186. font-size: $u-notify-text-font-size;
  187. text-align: center;
  188. }
  189. }
  190. &--primary {
  191. background-color: $u-notify-primary-bgColor;
  192. }
  193. &--success {
  194. background-color: $u-notify-success-bgColor;
  195. }
  196. &--error {
  197. background-color: $u-notify-error-bgColor;
  198. }
  199. &--warning {
  200. background-color: $u-notify-warning-bgColor;
  201. }
  202. }
  203. </style>