各位同学直接把下面代码复制进文档,把文档扔给AI,

跟AI说:‘请根据该文档帮我实现输入六格验证码的功能’

已经在uni真机实测输入和删除步骤都没有问题,建议使用claude sonnet 4.5

使用成功的话烦请回来点个赞哦

# uni-app 验证码输入框完整实现方案

## 一、功能需求

实现一个6位数字验证码输入框,具备以下特性:

- 6个独立的输入格子展示
- 输入数字后自动跳转到下一个格子
- 支持删除操作(兼容 H5 和 APP 端)
- 当前输入位置高亮显示
- 输入完成后自动触发提交
- 可选:显示闪烁光标

## 二、最佳实现方案

### 核心原理

采用**隐藏 input + 显示 view**的方案:

1. **隐藏的 input**:接收所有键盘输入(包括数字和删除),使用 `v-model` 绑定数据
2. **6个显示的 view**:仅用于展示,通过索引读取 input 的值
3. **删除逻辑**:由系统原生 input 自动处理,无需手动编写判断代码
4. **自动跳转**:通过监听 input 值的长度变化实现

### 为什么这个方案最优?

- ✅ 删除功能由系统原生处理,完美兼容所有平台
- ✅ 代码简洁,逻辑清晰,易于维护
- ✅ 无需维护复杂的状态数组和焦点控制
- ✅ 用户体验流畅,无卡顿

## 三、完整代码实现

### 3.1 模板部分(Template)

```vue
<template>
  <view class="code_page">
    <view class="code_content">
      <text class="code_title">验证码已发送至</text>
      <text class="phone_display">+86 138 0013 8000</text>

      <!-- 验证码输入框 -->
      <view class="code_input_group">
        <!-- 隐藏的真实输入框 -->
        <input class="hidden_input" type="number" maxlength="6" :focus="isCodePageVisible" v-model="verificationCode" @input="onCodeInput" />

        <!-- 显示的6个格子 -->
        <view class="code_input_item" v-for="(item, index) in 6" :key="index" @click="focusCodeInput" :class="{ active: verificationCode.length === index }">
          {{ verificationCode[index] || "" }}
          <!-- 可选:闪烁光标 -->
          <view class="cursor" v-if="verificationCode.length === index"></view>
        </view>
      </view>

      <!-- 重新发送 -->
      <view class="resend_section">
        <text v-if="countdown > 0" class="resend_text disabled"> 重新发送 {{ countdown }}s </text>
        <text v-else class="resend_text" @click="resendCode"> 重新发送 </text>
      </view>
    </view>
  </view>
</template>
```

### 3.2 脚本部分(Script)

```javascript
<script setup>
import { ref } from 'vue'

// 验证码值
const verificationCode = ref('')

// 页面是否可见(用于控制输入框聚焦)
const isCodePageVisible = ref(true)

// 倒计时
const countdown = ref(60)

// 验证码输入处理
const onCodeInput = (e) => {
  const value = e.detail.value
  verificationCode.value = value

  // 输入完成自动提交
  if (value.length === 6) {
    setTimeout(() => {
      handleSubmit()
    }, 100)
  }
}

// 点击格子聚焦输入框
const focusCodeInput = () => {
  // 通过切换 focus 属性来重新聚焦
  isCodePageVisible.value = false
  setTimeout(() => {
    isCodePageVisible.value = true
  }, 0)
}

// 提交验证码
const handleSubmit = () => {
  console.log('提交验证码:', verificationCode.value)
  // 这里调用你的登录接口
  // await loginAPI(verificationCode.value)
}

// 重新发送验证码
const resendCode = () => {
  if (countdown.value > 0) return

  // 调用发送验证码接口
  console.log('重新发送验证码')

  // 重置倒计时
  countdown.value = 60
  const timer = setInterval(() => {
    countdown.value--
    if (countdown.value <= 0) {
      clearInterval(timer)
    }
  }, 1000)
}
</script>
```

### 3.3 样式部分(Style)

```scss
<style lang="scss" scoped>
.code_page {
  width: 100%;
  padding: 40px 32px;
}

.code_content {
  .code_title {
    display: block;
    text-align: center;
    font-size: 16px;
    color: #666666;
    margin-bottom: 8px;
  }

  .phone_display {
    display: block;
    text-align: center;
    font-size: 20px;
    font-weight: 600;
    color: #333333;
    margin-bottom: 40px;
  }

  .code_input_group {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 24px;
    position: relative;

    // 隐藏的输入框
    .hidden_input {
      position: absolute;
      left: -9999px;
      width: 1px;
      height: 1px;
      opacity: 0;
    }

    // 显示的格子
    .code_input_item {
      flex: 1;
      height: 50px;
      background: #f5f5f5;
      border-radius: 12px;
      border: 2px solid transparent;
      text-align: center;
      font-size: 24px;
      font-weight: 600;
      color: #333333;
      transition: all 0.3s ease;
      display: flex;
      align-items: center;
      justify-content: center;
      position: relative;

      // 当前输入位置高亮
      &.active {
        background: #ffffff;
        border-color: #1E88E5;
      }

      // 闪烁光标(可选)
      .cursor {
        position: absolute;
        width: 2px;
        height: 24px;
        background: #1E88E5;
        animation: blink 1s infinite;
      }
    }

    // 光标闪烁动画
    @keyframes blink {
      0%, 49% {
        opacity: 1;
      }
      50%, 100% {
        opacity: 0;
      }
    }
  }

  .resend_section {
    text-align: center;
    margin-bottom: 24px;

    .resend_text {
      font-size: 14px;
      color: #1E88E5;

      &.disabled {
        color: #999999;
      }
    }
  }
}
</style>
```

## 四、关键技术点说明

### 4.1 隐藏 input 的实现

```scss
.hidden_input {
  position: absolute;
  left: -9999px; // 移出可视区域
  width: 1px;
  height: 1px;
  opacity: 0; // 完全透明
}
```

**为什么不用 `display: none`?**

- `display: none` 会导致 input 无法获得焦点
- 使用 `position: absolute` + 移出屏幕的方式,input 仍然可以正常工作

### 4.2 自动跳转的实现

```javascript
const onCodeInput = (e) => {
  const value = e.detail.value;
  verificationCode.value = value;

  // 当输入满6位时自动提交
  if (value.length === 6) {
    setTimeout(() => {
      handleSubmit();
    }, 100);
  }
};
```

**说明**:

- 不需要手动控制焦点跳转
- 通过监听 `verificationCode` 的长度判断是否输入完成
- 使用 `setTimeout` 延迟提交,避免最后一个字符显示不完整

### 4.3 删除操作的实现

**关键点**:删除操作完全由系统原生 input 处理,无需编写任何代码!

工作原理:

1. 用户按删除键
2. 系统原生 input 自动删除最后一个字符
3. `v-model` 自动更新 `verificationCode` 的值
4. 显示的格子通过 `verificationCode[index]` 自动更新显示
5. 当前输入位置(高亮格子)自动向前移动

这就是"自动删除"的含义——删除逻辑由浏览器/系统原生处理,开发者无需编写任何判断代码。

### 4.4 重新聚焦的实现

```javascript
const focusCodeInput = () => {
  isCodePageVisible.value = false;
  setTimeout(() => {
    isCodePageVisible.value = true;
  }, 0);
};
```

**说明**:

- 通过切换 `:focus` 绑定的值来重新触发聚焦
- 先设为 `false` 失去焦点,再设为 `true` 重新聚焦

## 五、常见问题与解决方案

### Q1: 为什么 input 的 type 要用 "number"?

**答**:`type="number"` 会在移动端自动弹出数字键盘,提升用户体验。

### Q2: 如果需要支持字母+数字的验证码怎么办?

**答**:将 `type="number"` 改为 `type="text"` 即可。

### Q3: 如何自定义格子的样式?

**答**:修改 `.code_input_item` 的样式即可,例如:

```scss
.code_input_item {
  height: 60px; // 修改高度
  border-radius: 8px; // 修改圆角
  background: #fff; // 修改背景色
  border: 1px solid #ddd; // 添加边框
}
```

### Q4: 如何禁用自动提交?

**答**:删除 `onCodeInput` 中的自动提交逻辑:

```javascript
const onCodeInput = (e) => {
  const value = e.detail.value;
  verificationCode.value = value;
  // 删除这部分代码即可
  // if (value.length === 6) {
  //   setTimeout(() => {
  //     handleSubmit()
  //   }, 100)
  // }
};
```

### Q5: 如何去掉闪烁光标?

**答**:删除模板中的光标元素:

```vue
<!-- 删除这一行 -->
<view class="cursor" v-if="verificationCode.length === index"></view>
```

## 五、总结

**核心要点**:

1. 使用隐藏 input 接收输入,显示 view 展示内容
2. 删除操作交给系统原生处理,无需手动编写逻辑
3. 通过 `v-model` 绑定数据,自动同步状态
4. 代码简洁,逻辑清晰,易于维护

**适用场景**:

- ✅ 手机验证码输入
- ✅ 支付密码输入
- ✅ 邀请码输入
- ✅ 任何需要分格显示的输入场景

**兼容性**:

- ✅ uni-app H5
- ✅ uni-app APP(iOS/Android)
- ✅ uni-app 小程序(微信/支付宝等)

**方案优势**:

- 删除功能完美,由系统原生处理
- 输入流畅,无卡顿
- 代码量少,易于理解
- 维护成本低

---

**使用建议**:直接复制本文档中的完整代码,根据实际需求调整样式和业务逻辑即可快速实现验证码输入功能。将此文档提供给 AI 助手,AI 可以直接根据文档实现完整的验证码输入框功能。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐