cl-captcha.vue 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. <template>
  2. <view class="cl-captcha">
  3. <input
  4. class="cl-captcha__input"
  5. v-model="value2"
  6. type="number"
  7. :focus="focus"
  8. :maxlength="length"
  9. @focus="onFocus"
  10. @blur="onBlur"
  11. @input="onInput"
  12. />
  13. <view class="cl-captcha__code">
  14. <view
  15. class="cl-captcha__item"
  16. :style="{
  17. height: parseRpx(height),
  18. margin: `0 ${gutter}rpx`,
  19. }"
  20. v-for="(item, index) in list"
  21. :key="index"
  22. >
  23. <text class="cl-captcha__value">{{ value2[index] }}</text>
  24. <view class="cl-captcha__cursor" v-if="value2.length == index && focus2"></view>
  25. </view>
  26. </view>
  27. </view>
  28. </template>
  29. <script>
  30. import { parseRpx } from "../../utils";
  31. /**
  32. * captcha 验证码输入框
  33. * @description 支持位数
  34. * @tutorial https://docs.cool-js.com/uni/components/advanced/captcha.html
  35. * @property {String} value 绑定值
  36. * @property {Boolean} focus 是否聚焦
  37. * @property {String, Number} height 验证码高度,默认120rpx
  38. * @property {Number} length 验证码位数,默认4
  39. * @property {Number} gutter 间隔,默认20
  40. * @event {Function} done 输入完成时触发
  41. * @example <cl-captcha v-model="val"></cl-captcha>
  42. */
  43. export default {
  44. name: "cl-captcha",
  45. props: {
  46. // 绑定值
  47. value: String,
  48. // 是否聚焦
  49. focus: Boolean,
  50. // 验证码高度
  51. height: {
  52. type: [String, Number],
  53. default: "120rpx",
  54. },
  55. // 验证码位数
  56. length: {
  57. type: Number,
  58. default: 4,
  59. },
  60. // 间隔
  61. gutter: {
  62. type: Number,
  63. default: 20,
  64. },
  65. },
  66. data() {
  67. return {
  68. value2: null,
  69. focus2: false,
  70. };
  71. },
  72. watch: {
  73. value: {
  74. immediate: true,
  75. handler(val) {
  76. this.value2 = val || "";
  77. },
  78. },
  79. },
  80. computed: {
  81. list() {
  82. // 头条小程序下,无法 v-for 数字
  83. return new Array(this.length).fill(1);
  84. },
  85. },
  86. methods: {
  87. parseRpx,
  88. onFocus() {
  89. this.focus2 = true;
  90. },
  91. onBlur() {
  92. this.focus2 = false;
  93. },
  94. onInput(e) {
  95. const val = e.detail.value;
  96. this.$emit("input", val);
  97. if (val.length === this.length) {
  98. this.$emit("done", val);
  99. }
  100. },
  101. },
  102. };
  103. </script>