看起来高大上的验证码

总觉得自己的项目UI不是特别合理,参考了一些好的案例,发现了一个很棒的设计。动手实现了一下,在这里分享一下!

前言

在用户输入手机号后输入验证码时,验证码是分割开的。哎我也描述不太清楚,直接上图吧!

image-20210530131325431.png

在简单的思考?之后,参考掘金上面的一篇文章作了稍微的改动,实现了上述效果。看一下成品吧。

image-20210530131253209.png

整体思路

磨刀不误砍柴工,在动手之前,我们不妨先想一下,这样的效果是怎样实现的呢?难道是放置6个input,然后监听blur事件,当第一个input输入完毕后,第一个input失去焦点,然后第二个input获取焦点吧?总归是种办法,但是好像不是那么优雅!我自己觉得我们是一个艺术家,要写出来优雅的代码。

那优雅的代码如何写呢?且听我给你娓娓道来。

我们的核心是使用labelinputlabel有个for的属性,这个属性就是我们实现这个的关键。for是个什么东西?它是干什么用的?看看W3C怎么说:“for 属性规定 label 与哪个表单元素绑定。”

那么具体怎么搞呢?你想呀,如果我们有一个input用来接收用户输入的内容,然后我们根据input里面的内容去设置label显示的文本,那么是不是达到了目的呢?

说的有点乱,上个图!

vcode.png

如图所示,我们将用户输入的数据保存起来,然后让6个label分别读取内容就Ok了。

下面给出一个?

例子

我将其封装成了一个组件,?中将仅展示组件代码(防止代码多头晕)。

首先我们需要写出html部分,此处省去讲解

<template>
  <div class="vcode-wrapper">
    <div class="vcode-title">
      <h2>请输入收到的验证码</h2>
    </div>
    <div class="vcode-main">
      <input 
        type="tel"
        id="vcode"
        ref="vcode"
        maxlength="6"
        v-model="code"
        @focus="focused = true"
        @blur="focused = false">

      <label
        for="vcode"
        v-for="(item, index) in codeLength"
        :key="item"
        :class="{'focused': focused && cursorIndex === index}"
        v-text="codeArr[index]">
      </label>
    </div>
  </div>
</template>
复制代码

JS部分

<script>
export default {
  data() {
    return {
      // 验证码长度
      codeLength: 6,
      // 用户输入的验证码
      code: '',
      // input 聚焦状态
      focused: false
    }
  },
  computed: {
    codeArr() {
      return this.code.split('');
    },
    cursorIndex() {
      return this.code.length;
    }
  },
  watch: {
    code(newVal) {
      this.code = newVal.replace(/[^\d]/g, '');
      if (this.code.length > 5) {
        this.focused = false;
        this.$refs.vcode.blur();
        setTimeout(() => {
          alert(`验证码: ${this.code}`)
        }, 500)
      }
    }
  }
}
</script>
复制代码

CSS部分

.vcode-main {
  display: flex;
}
.vcode-main input {
  position: absolute;
  top: 0;
  left: 0;
  opacity: 0;
}
.vcode-main label {
  display: inline-block;
  font-size: 1.5rem;
  padding: 0.3em;
  height: 32px;
  width: 32px;
  border: 1px solid #ddd;
  line-height: 32px;
  text-align: center;
  border-radius: 0.5em;
}
.vcode-main label + label {
  margin-left: 0.5em;
}
.focused::before {
  display: block;
  content: '';
  position: relative;
  left: 15px;
  top: 4px;
  width: 2px;
  height: 24px;
  background-color: #ccc;
  animation: opacity1_0 1s infinite;
}
@keyframes opacity1_0 {
  from {
    opacity: 1;
  }
  25% {
    opacity: 1;
  }
  50% {
    opacity: 0.8;
  }
  75% {
    opacity: 0;
  }
  to {
    opacity: 0;
  }
}
复制代码

最后

周末了不做那么烧脑的事情,简简单单做个小Demo,祝大家周末愉快。

?难免有不完善的地方,烦请各路大牛批的轻一点点。

如果愿意交个朋友,欢迎骚扰。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享