u-toast.vue 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. <template>
  2. <view :class="[isShow ? 'u-show' : '', 'u-type-' + tmpConfig.type, 'u-position-' + tmpConfig.position]"
  3. :style="{
  4. zIndex: uZIndex
  5. }" class="u-toast">
  6. <view class="u-icon-wrap">
  7. <u-icon v-if="tmpConfig.icon" :color="tmpConfig.type" :name="iconName" :size="30" class="u-icon"></u-icon>
  8. </view>
  9. <text class="u-text">{{ tmpConfig.title }}</text>
  10. </view>
  11. </template>
  12. <script>
  13. /**
  14. * toast 消息提示
  15. * @description 此组件表现形式类似uni的uni.showToastAPI,但也有不同的地方。
  16. * @tutorial https://www.uviewui.com/components/toast.html
  17. * @property {String} z-index toast展示时的z-index值
  18. * @event {Function} show 显示toast,如需一进入页面就显示toast,请在onReady生命周期调用
  19. * @example <u-toast ref="uToast" />
  20. */
  21. export default {
  22. name: "u-toast",
  23. props: {
  24. // z-index值
  25. zIndex: {
  26. type: [Number, String],
  27. default: ''
  28. },
  29. },
  30. data() {
  31. return {
  32. isShow: false,
  33. timer: null, // 定时器
  34. config: {
  35. params: {}, // URL跳转的参数,对象
  36. title: '', // 显示文本
  37. type: '', // 主题类型,primary,success,error,warning,black
  38. duration: 2000, // 显示的时间,毫秒
  39. isTab: false, // 是否跳转tab页面
  40. url: '', // toast消失后是否跳转页面,有则跳转,优先级高于back参数
  41. icon: true, // 显示的图标
  42. position: 'center', // toast出现的位置
  43. callback: null, // 执行完后的回调函数
  44. back: false, // 结束toast是否自动返回上一页
  45. },
  46. tmpConfig: {}, // 将用户配置和内置配置合并后的临时配置变量
  47. };
  48. },
  49. computed: {
  50. iconName() {
  51. // 只有不为none,并且type为error|warning|succes|info时候,才显示图标
  52. if (['error', 'warning', 'success', 'info'].indexOf(this.tmpConfig.type) >= 0 && this.tmpConfig.icon) {
  53. let icon = this.$u.type2icon(this.tmpConfig.type);
  54. return icon;
  55. }
  56. },
  57. uZIndex() {
  58. // 显示toast时候,如果用户有传递z-index值,有限使用
  59. return this.isShow ? (this.zIndex ? this.zIndex : this.$u.zIndex.toast) : '999999';
  60. }
  61. },
  62. methods: {
  63. // 显示toast组件,由父组件通过this.$refs.xxx.show(options)形式调用
  64. show(options) {
  65. // 不降结果合并到this.config变量,避免多次条用u-toast,前后的配置造成混论
  66. this.tmpConfig = this.$u.deepMerge(this.config, options);
  67. if (this.timer) {
  68. // 清除定时器
  69. clearTimeout(this.timer);
  70. this.timer = null;
  71. }
  72. this.isShow = true;
  73. this.timer = setTimeout(() => {
  74. // 倒计时结束,清除定时器,隐藏toast组件
  75. this.isShow = false;
  76. clearTimeout(this.timer);
  77. this.timer = null;
  78. // 判断是否存在callback方法,如果存在就执行
  79. typeof (this.tmpConfig.callback) === 'function' && this.tmpConfig.callback();
  80. this.timeEnd();
  81. }, this.tmpConfig.duration);
  82. },
  83. // 隐藏toast组件,由父组件通过this.$refs.xxx.hide()形式调用
  84. hide() {
  85. this.isShow = false;
  86. if (this.timer) {
  87. // 清除定时器
  88. clearTimeout(this.timer);
  89. this.timer = null;
  90. }
  91. },
  92. // 倒计时结束之后,进行的一些操作
  93. timeEnd() {
  94. // 如果带有url值,根据isTab为true或者false进行跳转
  95. if (this.tmpConfig.url) {
  96. // 如果url没有"/"开头,添加上,因为uni的路由跳转需要"/"开头
  97. if (this.tmpConfig.url[0] != '/') this.tmpConfig.url = '/' + this.tmpConfig.url;
  98. // 判断是否有传递显式的参数
  99. if (Object.keys(this.tmpConfig.params).length) {
  100. // 判断用户传递的url中,是否带有参数
  101. // 使用正则匹配,主要依据是判断是否有"/","?","="等,如“/page/index/index?name=mary"
  102. // 如果有params参数,转换后无需带上"?"
  103. let query = '';
  104. if (/.*\/.*\?.*=.*/.test(this.tmpConfig.url)) {
  105. // object对象转为get类型的参数
  106. query = this.$u.queryParams(this.tmpConfig.params, false);
  107. this.tmpConfig.url = this.tmpConfig.url + "&" + query;
  108. } else {
  109. query = this.$u.queryParams(this.tmpConfig.params);
  110. this.tmpConfig.url += query;
  111. }
  112. }
  113. // 如果是跳转tab页面,就使用uni.switchTab
  114. if (this.tmpConfig.isTab) {
  115. uni.switchTab({
  116. url: this.tmpConfig.url
  117. });
  118. } else {
  119. uni.navigateTo({
  120. url: this.tmpConfig.url
  121. });
  122. }
  123. } else if (this.tmpConfig.back) {
  124. // 回退到上一页
  125. this.$u.route({
  126. type: 'back'
  127. })
  128. }
  129. }
  130. }
  131. };
  132. </script>
  133. <style lang="scss" scoped>
  134. @import "../../libs/css/style.components.scss";
  135. .u-toast {
  136. position: fixed;
  137. z-index: -1;
  138. transition: opacity 0.3s;
  139. text-align: center;
  140. color: #fff;
  141. border-radius: 8 rpx;
  142. background: #585858;
  143. @include vue-flex;
  144. align-items: center;
  145. justify-content: center;
  146. font-size: 28 rpx;
  147. opacity: 0;
  148. pointer-events: none;
  149. padding: 18 rpx 40 rpx;
  150. }
  151. .u-toast.u-show {
  152. opacity: 1;
  153. }
  154. .u-icon {
  155. margin-right: 10 rpx;
  156. @include vue-flex;
  157. align-items: center;
  158. line-height: normal;
  159. }
  160. .u-position-center {
  161. left: 50%;
  162. top: 50%;
  163. transform: translate(-50%, -50%);
  164. /* #ifndef APP-NVUE */
  165. max-width: 70%;
  166. /* #endif */
  167. }
  168. .u-position-top {
  169. left: 50%;
  170. top: 20%;
  171. transform: translate(-50%, -50%);
  172. }
  173. .u-position-bottom {
  174. left: 50%;
  175. bottom: 20%;
  176. transform: translate(-50%, -50%);
  177. }
  178. .u-type-primary {
  179. color: $u-type-primary;
  180. background-color: $u-type-primary-light;
  181. border: 1px solid rgb(215, 234, 254);
  182. }
  183. .u-type-success {
  184. color: $u-type-success;
  185. background-color: $u-type-success-light;
  186. border: 1px solid #BEF5C8;
  187. }
  188. .u-type-error {
  189. color: $u-type-error;
  190. background-color: $u-type-error-light;
  191. border: 1px solid #fde2e2;
  192. }
  193. .u-type-warning {
  194. color: $u-type-warning;
  195. background-color: $u-type-warning-light;
  196. border: 1px solid #faecd8;
  197. }
  198. .u-type-info {
  199. color: $u-type-info;
  200. background-color: $u-type-info-light;
  201. border: 1px solid #ebeef5;
  202. }
  203. .u-type-default {
  204. color: #fff;
  205. background-color: #585858;
  206. }
  207. </style>