vue之封装验证码输入框

320 阅读1分钟

核心: KeyDown()功能:检查用户是否按了键盘上指定的键

代码:

<template>
  <div>
    <div id="app">
      <div class="container">
        <div class="code-container">
          <input
            v-for="(code, index) in codes"
            :key="index"
            type="number"
            class="code"
            placeholder="0"
            min="0"
            max="9"
            required
            ref="codeInput"
            v-model="codes[index]"
            @keydown="handleKeyDown(index, $event)"
          />
        </div>
        <button class="submit-btn" @click="submit">获取输入的验证码</button>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  components: {},
  data() {
    return {
      codes: [0, 0, 0, 0, 0, 0],
      timer: null,
    };
  },
  mounted() {
    this.$nextTick(() => {
      this.$refs.codeInput[0].focus();
    });
  },
  methods: {
    handleKeyDown(index, event) {
      if (event.key >= 0 && event.key <= 9) {
        this.codes.splice(index, 1, "");
        this.timer = setTimeout(() => {
          if (index < this.codes.length - 1) {
            this.$refs.codeInput[index + 1].focus();
          }
        }, 10);
      } else if (event.key === "Backspace") {
        this.timer = setTimeout(() => {
          if (index > 0) {
            this.$refs.codeInput[index - 1].focus();
          }
        }, 10);
      }
    },
    submit() {
      console.log(this.codes);
    },
  },
  beforeDestroy() {
    clearTimeout(this.timer); // 清除定时器
  },
};
</script>

<style lang="scss" scoped>
* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
}

.container {
  background-color: #fff;
  border-radius: 10px;
  padding: 30px;
  max-width: 1000px;
  text-align: center;
  margin: 0 auto;
}

.code-container {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 40px 0;
}

.code {
  caret-color: transparent;
  border-radius: 5px;
  font-size: 75px;
  height: 120px;
  width: 100px;
  border: 1px solid #eee;
  margin: 1%;
  text-align: center;
  font-weight: 300;
  -moz-appearance: textfield;
}

.code::-webkit-outer-spin-button,
.code::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.code:valid {
  border-color: #3498db;
  box-shadow: 0 10px 10px -5px rgba(0, 0, 0, 0.25);
}

.submit-btn {
  background-color: #eaeaea;
  display: inline-block;
  padding: 10px;
  line-height: 20px;
  max-width: 400px;
  color: #777;
  border-radius: 5px;
  border: none;
}

@media (max-width: 600px) {
  .code-container {
    flex-wrap: wrap;
  }

  .code {
    font-size: 60px;
    height: 80px;
    max-width: 70px;
  }
}
</style>

效果图:

GIF 2023-7-14 15-08-57.gif