tui-countdown-verify.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. <template>
  2. <view
  3. class="tui-countdown__verify"
  4. :class="{ 'tui-verify__opacity': status > 1 && isOpacity }"
  5. :style="{ width: width, height: height, padding: padding, margin: margin, borderRadius: radius, fontSize: size + 'rpx', color: color, background: background }"
  6. :hover-class="hover && status == 1 ? 'tui-verify__opacity' : ''"
  7. :hover-stay-time="150"
  8. @tap.stop="sendCode"
  9. >
  10. {{ showText }}
  11. <view class="tui-verify__line" :style="{ borderWidth: borderWidth, borderColor: borderColor, borderRadius: radius }"></view>
  12. </view>
  13. </template>
  14. <script>
  15. export default {
  16. name: 'tuiCountdownVerify',
  17. emits: ['send','countdown','end'],
  18. props: {
  19. //发送前显示文本
  20. text: {
  21. type: String,
  22. default: '发送验证码'
  23. },
  24. //发送中显示文本
  25. sendText: {
  26. type: String,
  27. default: '请稍候...'
  28. },
  29. //发送后显示文本(前面会自动加上seconds)
  30. countdownText: {
  31. type: String,
  32. default: 's后获取'
  33. },
  34. //倒计时秒数
  35. seconds: {
  36. type: Number,
  37. default: 60
  38. },
  39. //宽度
  40. width: {
  41. type: String,
  42. default: '182rpx'
  43. },
  44. //高度
  45. height: {
  46. type: String,
  47. default: '56rpx'
  48. },
  49. padding: {
  50. type: String,
  51. default: '0'
  52. },
  53. margin: {
  54. type: String,
  55. default: '0'
  56. },
  57. //圆角
  58. radius: {
  59. type: String,
  60. default: '6rpx'
  61. },
  62. //字体大小 rpx
  63. size: {
  64. type: Number,
  65. default: 24
  66. },
  67. //字体颜色
  68. color: {
  69. type: String,
  70. default: '#5677fc'
  71. },
  72. //背景色
  73. background: {
  74. type: String,
  75. default: 'transparent'
  76. },
  77. //边框宽度
  78. borderWidth: {
  79. type: String,
  80. default: '1px'
  81. },
  82. //边框颜色
  83. borderColor: {
  84. type: String,
  85. default: '#5677fc'
  86. },
  87. //倒计时的时候是否改变opacity值
  88. isOpacity: {
  89. type: Boolean,
  90. default: true
  91. },
  92. //是否需要点击效果
  93. hover: {
  94. type: Boolean,
  95. default: true
  96. },
  97. //短信发送成功(改变数值且数值大于0表示发送成功,多次发送数值递增即可)
  98. successVal: {
  99. type: Number,
  100. default: 0
  101. },
  102. //重置组件状态(改变数值且数值大于0,多次重置数值递增即可)
  103. resetVal: {
  104. type: Number,
  105. default: 0
  106. },
  107. //是否默认为倒计时状态
  108. start:{
  109. type:Boolean,
  110. default:false
  111. },
  112. //自定义参数
  113. params: {
  114. type: [Number, String],
  115. default: 0
  116. }
  117. },
  118. data() {
  119. return {
  120. showText: '',
  121. //1-发送前,2-发送中 3-发送成功,倒计时
  122. status: 1,
  123. countdownTimer: null
  124. };
  125. },
  126. created() {
  127. if(this.start){
  128. this.doLoop();
  129. }else{
  130. this.showText = this.text;
  131. this.clearTimer();
  132. }
  133. },
  134. // #ifndef VUE3
  135. beforeDestroy() {
  136. this.clearTimer();
  137. },
  138. // #endif
  139. // #ifdef VUE3
  140. beforeUnmount() {
  141. this.clearTimer();
  142. },
  143. // #endif
  144. watch: {
  145. successVal(val) {
  146. if (val && val > 0) {
  147. this.doLoop();
  148. }
  149. },
  150. resetVal(val) {
  151. if (val && val > 0) {
  152. this.reset();
  153. }
  154. }
  155. },
  156. methods: {
  157. sendCode() {
  158. if (this.status > 1) return;
  159. this.clearTimer();
  160. this.status = 2;
  161. this.showText = this.sendText;
  162. this.$emit('send', {
  163. params: this.params
  164. });
  165. },
  166. doLoop: function() {
  167. this.clearTimer();
  168. this.status = 3;
  169. let seconds = this.seconds || 60;
  170. this.showText = seconds + this.countdownText;
  171. this.countdownTimer = setInterval(() => {
  172. if (seconds > 1) {
  173. --seconds;
  174. this.showText = seconds + this.countdownText;
  175. //倒计时
  176. this.$emit('countdown', {
  177. seconds: seconds,
  178. params: this.params
  179. });
  180. } else {
  181. this.reset();
  182. //倒计时结束
  183. this.$emit('end', {
  184. params: this.params
  185. });
  186. }
  187. }, 1000);
  188. },
  189. //验证码发送成功
  190. success() {
  191. this.doLoop();
  192. },
  193. //重置发送组件
  194. reset() {
  195. this.clearTimer();
  196. this.showText = this.text;
  197. this.status = 1;
  198. },
  199. clearTimer() {
  200. clearInterval(this.countdownTimer);
  201. this.countdownTimer = null;
  202. }
  203. }
  204. };
  205. </script>
  206. <style scoped>
  207. .tui-countdown__verify {
  208. position: relative;
  209. display: flex;
  210. align-items: center;
  211. justify-content: center;
  212. white-space: nowrap;
  213. box-sizing: border-box;
  214. }
  215. .tui-verify__opacity {
  216. opacity: 0.5;
  217. }
  218. .tui-verify__line {
  219. position: absolute;
  220. width: 200%;
  221. height: 200%;
  222. transform-origin: 0 0;
  223. transform: scale(0.5, 0.5) translateZ(0);
  224. box-sizing: border-box;
  225. border-style: solid;
  226. left: 0;
  227. top: 0;
  228. pointer-events: none;
  229. }
  230. </style>