uni-id-pages-email-form.vue 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. <template>
  2. <view>
  3. <uni-captcha :focus="focusCaptchaInput" ref="captcha" scene="send-email-code" v-model="captcha" />
  4. <view class="box">
  5. <uni-easyinput :focus="focusEmailCodeInput" @blur="focusEmailCodeInput = false" type="number" class="input-box" :inputBorder="false" v-model="modelValue" maxlength="6"
  6. placeholder="请输入邮箱验证码">
  7. </uni-easyinput>
  8. <view class="short-code-btn" hover-class="hover" @click="start">
  9. <text class="inner-text" :class="reverseNumber==0?'inner-text-active':''">{{innerText}}</text>
  10. </view>
  11. </view>
  12. </view>
  13. </template>
  14. <script>
  15. function debounce(func, wait) {
  16. let timer;
  17. wait = wait || 500;
  18. return function() {
  19. let context = this;
  20. let args = arguments;
  21. if (timer) clearTimeout(timer);
  22. let callNow = !timer;
  23. timer = setTimeout(() => {
  24. timer = null;
  25. }, wait)
  26. if (callNow) func.apply(context, args);
  27. }
  28. }
  29. /**
  30. * email-code-form
  31. * @description 获取邮箱验证码组件
  32. * @tutorial https://ext.dcloud.net.cn/plugin?id=
  33. * @property {Number} count 倒计时时长 s
  34. * @property {String} email 邮箱
  35. * @property {String} type = [login-by-email-code|reset-pwd-by-email-code|bind-email] 验证码类型,用于防止不同功能的验证码混用,目前支持的类型login登录、register注册、bind绑定邮箱、unbind解绑邮箱
  36. * @property {false} focusCaptchaInput = [true|false] 验证码输入框是否默认获取焦点
  37. */
  38. export default {
  39. name: "uni-email-code-form",
  40. model: {
  41. prop: 'modelValue',
  42. event: 'update:modelValue'
  43. },
  44. props: {
  45. event: ['update:modelValue'],
  46. /**
  47. * 倒计时时长 s
  48. */
  49. count: {
  50. type: [String, Number],
  51. default: 60
  52. },
  53. /**
  54. * 邮箱
  55. */
  56. email: {
  57. type: [String],
  58. default: ''
  59. },
  60. /*
  61. 验证码类型,用于防止不同功能的验证码混用,目前支持的类型login登录、register注册、bind绑定邮箱、unbind解绑邮箱
  62. */
  63. type: {
  64. type: String,
  65. default () {
  66. return 'register'
  67. }
  68. },
  69. /*
  70. 验证码输入框是否默认获取焦点
  71. */
  72. focusCaptchaInput: {
  73. type: Boolean,
  74. default () {
  75. return false
  76. }
  77. },
  78. },
  79. data() {
  80. return {
  81. captcha: "",
  82. reverseNumber: 0,
  83. reverseTimer: null,
  84. modelValue: "",
  85. focusEmailCodeInput:false
  86. };
  87. },
  88. watch: {
  89. captcha(value, oldValue) {
  90. if (value.length == 4 && oldValue.length != 4) {
  91. this.start()
  92. }
  93. },
  94. modelValue(value) {
  95. // TODO 兼容 vue2
  96. this.$emit('input', value);
  97. // TODO 兼容 vue3
  98. this.$emit('update:modelValue', value)
  99. }
  100. },
  101. computed: {
  102. innerText() {
  103. if (this.reverseNumber == 0) return "获取邮箱验证码";
  104. return "重新发送" + '(' + this.reverseNumber + 's)';
  105. }
  106. },
  107. created() {
  108. this.initClick();
  109. },
  110. methods: {
  111. getImageCaptcha(focus) {
  112. this.$refs.captcha.getImageCaptcha(focus)
  113. },
  114. initClick() {
  115. this.start = debounce(() => {
  116. if (this.reverseNumber != 0) return;
  117. this.sendMsg();
  118. })
  119. },
  120. sendMsg() {
  121. if (this.captcha.length != 4) {
  122. this.$refs.captcha.focusCaptchaInput = true
  123. return uni.showToast({
  124. title: '请先输入图形验证码',
  125. icon: 'none'
  126. });
  127. }
  128. if(!this.email) return uni.showToast({
  129. title: "请输入邮箱",
  130. icon: 'none'
  131. });
  132. let reg_email = /@/;
  133. if (!reg_email.test(this.email)) return uni.showToast({
  134. title: "邮箱格式错误",
  135. icon: 'none'
  136. });
  137. const uniIdCo = uniCloud.importObject("uni-id-co", {
  138. customUI: true
  139. })
  140. console.log('uniIdCo', uniIdCo)
  141. console.log('sendEmailCode',{
  142. "email": this.email,
  143. "scene": this.type,
  144. "captcha": this.captcha
  145. });
  146. uniIdCo.sendEmailCode({
  147. "email": this.email,
  148. "scene": this.type,
  149. "captcha": this.captcha
  150. }).then(result => {
  151. console.log(result.code);
  152. uni.showToast({
  153. title: "邮箱验证码发送成功",
  154. icon: 'none'
  155. });
  156. this.reverseNumber = Number(this.count);
  157. this.getCode();
  158. }).catch(e => {
  159. console.log(JSON.stringify(e));
  160. if (e.code == "uni-id-invalid-mail-template") {
  161. this.modelValue = "123456"
  162. uni.showToast({
  163. title: '已启动测试模式,详情【控制台信息】',
  164. icon: 'none',
  165. duration: 3000
  166. });
  167. console.warn(e.message);
  168. } else {
  169. this.getImageCaptcha()
  170. this.captcha = ""
  171. uni.showToast({
  172. title: e.message,
  173. icon: 'none'
  174. });
  175. }
  176. })
  177. },
  178. getCode() {
  179. if (this.reverseNumber == 0) {
  180. clearTimeout(this.reverseTimer);
  181. this.reverseTimer = null;
  182. return;
  183. }
  184. this.reverseNumber--;
  185. this.reverseTimer = setTimeout(() => {
  186. this.getCode();
  187. }, 1000)
  188. }
  189. }
  190. }
  191. </script>
  192. <style lang="scss" scoped>
  193. .box {
  194. position: relative;
  195. margin-top: 10px;
  196. }
  197. .short-code-btn {
  198. padding: 0;
  199. position: absolute;
  200. top: 0;
  201. right: 8px;
  202. width: 260rpx;
  203. max-width: 130px;
  204. height: 44px;
  205. /* #ifndef APP-NVUE */
  206. display: flex;
  207. /* #endif */
  208. justify-content: center;
  209. align-items: center;
  210. }
  211. .inner-text {
  212. font-size: 14px;
  213. color: #AAAAAA;
  214. }
  215. .inner-text-active {
  216. color: #04498c;
  217. }
  218. .captcha {
  219. width: 350rpx;
  220. }
  221. .input-box {
  222. margin: 0;
  223. padding: 4px;
  224. background-color: #F8F8F8;
  225. font-size: 14px;
  226. }
  227. .box ::v-deep .content-clear-icon {
  228. margin-right: 100px;
  229. }
  230. .box {
  231. /* #ifndef APP-NVUE */
  232. display: flex;
  233. /* #endif */
  234. flex-direction: row;
  235. }
  236. </style>