u-toast.vue 6.4 KB

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