vue3 setup 语法 + ant-vue-design 实现验证码输入框效果

vue3 setup 语法 + ant-vue-design 实现验证码输入框效果 有光标效果
新增一个组件input-code.vue, 然后复制下面全部组件代码就行

效果图如下
在这里插入图片描述

组件代码:

// input-code.vue
<template>
  <div>
    <div class="input-code">
      <span class="code" v-for="(item, index) in count" :key="index">
        <span>{{ getReadNum(index) }}</span>
        <span v-if="index === currentIndex && isFocused" class="cursor"></span>
      </span>
      <a-input
        type="password"
        class="input"
        :maxlength="count"
        v-model:value="codeValue"
        @input="updateCursor"
        @keydown="handleKeyDown"
        @focus="isFocused = true"
        @blur="isFocused = false"
        ref="inputRef"
      />
    </div>
  </div>
</template>

<script setup>
  import { ref, watch, onMounted } from 'vue';

  const props = defineProps({
  	// 验证码数量 长度
    count: {
      type: Number,
      default: 6
    },
    // input 值
    value: {
      type: String,
      default: ''
    },
    // 自动获取焦点
    autoFocus: {
      type: Boolean,
      default: false
    }
  });

  const emit = defineEmits(['update:value']);

  const codeValue = ref('');
  const currentIndex = ref(0);
  const isFocused = ref(false); // 控制光标闪烁的状态
  const inputRef = ref(null); // 用于引用输入框

  const getReadNum = (index) => {
    let arr = String(codeValue.value)
      .split('')
      .map(() => '*');
    return arr[index];
  };

  const updateCursor = () => {
    currentIndex.value = codeValue.value.length; // 更新光标位置
    emit('update:value', codeValue.value);
  };

  const handleKeyDown = (event) => {
    if (event.ctrlKey && event.key === 'a') {
      event.preventDefault(); // 阻止 Ctrl + A 全选
    }
  };

  watch(
    () => props.value,
    (val) => {
      codeValue.value = val;
    },
    { immediate: true }
  );

  onMounted(() => {
    if (props.autoFocus) {
      inputRef.value.focus(); // 自动获取焦点
    }
  });
</script>

<style lang="less" scoped>
  .input-code {
    position: relative;
    width: 450px;
    margin: 20px auto;
    display: flex;
    align-items: center;
    vertical-align: baseline;
    justify-content: space-between;

    .code {
      display: block;
      height: 65px;
      width: 65px;
      background-color: rgb(51, 146, 153);
      border-radius: 5px;
      color: #fff;
      font-size: 28px;
      display: flex;
      align-items: center;
      justify-content: center;
      position: relative;

      .cursor {
        position: absolute;
        width: 1px;
        height: 55%;
        background-color: #fff;
        animation: blink 1s step-end infinite; /* 闪烁效果 */
        top: 50%;
        transform: translate(-50%, -50%);
      }

      span {
        position: relative;
        top: 6px;
        font-size: 40px;
      }
    }

    .input {
      position: absolute;
      height: 65px;
      opacity: 0;
    }
  }

  @keyframes blink {
    0%,
    100% {
      opacity: 1;
    }
    50% {
      opacity: 0;
    }
  }
</style>

使用组件

// index.vue

<template>
  <div>
    <input-code v-model:value="codeValue" :autoFocus="true" />
  </div>
</template>

<script setup>
  import { ref } from 'vue';
  import InputCode from './components/input-code.vue';
  const codeValue = ref('');
  
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值