CaptchaInput.vue 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. <template>
  2. <!-- 格子验证码输入组件 -->
  3. <div class="row-center captcha_input_wrap">
  4. <input
  5. v-for="(item, index) in captchas"
  6. :key="index"
  7. v-model="item.num"
  8. :id="'captcha' + index"
  9. @input="inputFinash(index)"
  10. @focus="adjust(index)"
  11. @keydown="(e)=>{inputDirection(index,e)}"
  12. class="captcha_input_box row-center"
  13. :class="[index <= activeInput ? 'active' : '']"
  14. type="tel"
  15. maxlength="1"
  16. />
  17. </div>
  18. </template>
  19. <script>
  20. export default {
  21. data() {
  22. return {
  23. // 当前输入框
  24. activeInput: 0,
  25. captchas: [
  26. { num: "" },
  27. { num: "" },
  28. { num: "" },
  29. { num: "" },
  30. { num: "" },
  31. { num: "" },
  32. ],
  33. };
  34. },
  35. // 页面加载后聚焦第一个
  36. mounted() {
  37. let dom = document.getElementById("captcha" + this.activeInput);
  38. dom.focus();
  39. },
  40. methods: {
  41. // 自动校准输入顺序
  42. adjust(index) {
  43. let dom = document.getElementById("captcha" + this.activeInput);
  44. if (index !== this.activeInput && dom) {
  45. dom.focus();
  46. }
  47. },
  48. // 控制前后方向
  49. inputDirection(index,e) {
  50. let val = this.captchas[index].num;
  51. // 回退键处理
  52. if (e.key==='Backspace' && val === "") {
  53. // 重新校准
  54. let dom = document.getElementById("captcha" + (index - 1));
  55. this.activeInput = index - 1;
  56. if (dom) dom.focus();
  57. }
  58. if (e.key!=='Backspace' && val !== "") {
  59. let dom = document.getElementById("captcha" + (index + 1));
  60. this.activeInput = index + 1;
  61. if (dom) dom.focus();
  62. }
  63. },
  64. // 输入框相互联动
  65. inputFinash(index) {
  66. let val = this.captchas[index].num;
  67. this.activeInput = val ? index + 1 : index - 1;
  68. let dom = document.getElementById("captcha" + this.activeInput);
  69. if (dom) dom.focus();
  70. if (index == this.captchas.length - 1) {
  71. let code = this.captchas.map((x) => x.num).join("");
  72. if (code.length == 6) {
  73. this.$emit("finish", code);
  74. }
  75. }
  76. },
  77. },
  78. };
  79. </script>
  80. <style scoped lang='scss'>
  81. .row-center {
  82. display: flex;
  83. flex-direction: row;
  84. justify-content: center;
  85. align-items: center;
  86. gap:40px;
  87. }
  88. .captcha_input_wrap {
  89. width: 100%;
  90. }
  91. .captcha_input_box {
  92. width: 40px;
  93. height: 40px;
  94. background: rgba(255, 255, 255, 1);
  95. border-radius: 6px;
  96. border: 1px solid #dddddd;
  97. font-size: 16px;
  98. text-align: center;
  99. color: #1e243a;
  100. outline: none;
  101. }
  102. .active {
  103. border: 1px solid #3654C1 !important;
  104. }
  105. @media screen and (max-width:650px) {
  106. .row-center {
  107. gap:10px;
  108. }
  109. .captcha_input_box{
  110. box-sizing: border-box;
  111. }
  112. }
  113. </style>