vue payment password component

vue payment password component

We want to make a 6-digit password component similar to Jingdong and Alipay when paying, the effect is as follows.

Written specifically for PC . Many frameworks on the mobile terminal are basically already available, and the implementation logic will be simpler than that of the PC. Because the mobile terminal is generally equipped with a separate keyboard, it does not even need an input box , and does not need to consider the mouse, so the processing of the focus point will be simpler. And there is no hassle of password autocomplete on mobile.

If you use the input password component on the PC side (refer to the article: https://www.jianshu.com/p/03d2a4744258 ), chrome will pop up a password management window no matter what. If autocomplete=new-password is used, the password management window will pop up although it will not be automatically filled. So we use the input text/tel component and then cover it with • or *.

The overall code of Vue is as follows:

<template>
  <div :id="`ids_${id}`" class="m-password-input">
    <div v-for="(v, i) in 6" :key="i" class="box-input">
      <div v-show="pwdList[i]" class="u-dot" @click="changePwd">•</div>
      <input
        :key="i"
        v-model="pwdList[i]"
        type="tel"
        readonly
        onfocus="this.removeAttribute('readonly');"
        maxlength="1"
        autocomplete="new-password"
        class="u-input"
        @input="changeInput"
        @click="changePwd"
        @keyup="keyUp($event)"
        @keydown="oldPwdList = pwdList.length"
      >
    </div>
  </div>
</template>

<script>
export default {
  props: {
    id: {
      type: Number,
      default: 1 // 当一个页面有多个密码输入框时,用id来区分
    }
  },
  data() {
    return {
      pwdList: [],
      pwdListReal: [],
      oldPwdList: [],
      isDelete: false,
      ipt: ''
    }
  },
  mounted() {
    this.ipt = document.querySelectorAll(`#ids_${this.id} .u-input`)
  },
  methods: {
    keyUp(ev) {
      let index = this.pwdList.length
      if (!index) return
      if (ev.keyCode === 8) {
        this.isDelete = true
        if (this.oldPwdList === this.pwdList.length) {
          if (index === this.pwdList.length) {
            this.pwdList.pop()
          }
          index--
        } else {
          index > 0 && index--
        }
        this.ipt[index].focus()
      } else if (this.isDelete && index === this.pwdList.length && /^\d$/.test(ev.key)) {
        this.isDelete = false
        this.pwdList.pop()
        this.pwdList.push(ev.key)
        this.ipt[this.pwdList.length] && this.ipt[this.pwdList.length].focus()
      }
      this.$emit('get-pwd', this.pwdList.join(''))
    },
    changePwd() {
      let index = this.pwdList.length
      index === 6 && index--
      this.ipt[index].focus()
    },
    changeInput() {
      let index = this.pwdList.length
      const val = this.pwdList[index - 1]
      if (!/[0-9]/.test(val)) {
        this.pwdList.pop()
        return
      }
      if (!val) {
        this.pwdList.pop()
        index--
        if (index > 0) this.ipt[index - 1].focus()
      } else {
        if (index < 6) this.ipt[index].focus()
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.m-password-input {
  display: flex;
  border-radius: 5px;
  padding: 10px 0;
  border: 1px solid #cccccc;
  position: relative;
  margin-left: 1px;
  .box-input {
    display: inline-block;
    position: relative;
    border-right: 1px solid #cccccc;
    &:last-child{
      border-right:0;
    }
    .u-dot {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 40px;
    }
    .u-input {
      text-align: center;
      font-size: 30px;
      float: left;
      width: 40px;
      height: 20px !important;
      color: transparent;
      caret-color: #333333;
      outline: unset;
      border: none;
      border-right: 1px solid #cccccc;
      &:last-child{
        border-right:0;
      }
    }
  }
}
</style>

use:

<password-input @get-pwd="getPwd" />
import PasswordInput from '@/components/PasswordInput'
methods: {
    getPwd(password) {
      console.log(password)
    }
  }

Reference article:

{{o.name}}
{{m.name}}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324113986&siteId=291194637