关于vue.js:vue-封装-密码框

2次阅读

共计 2394 个字符,预计需要花费 6 分钟才能阅读完成。

<template>
  <div class="password-number" :class="{gutter: gutter != 0}">
    <div
      class="password-item"
      :class="{gutter: gutter != 0}"
      :style="{margin: `0 ${gutter}px` }"
      v-for="(item, index) in length"
      :key="index"
    >
      <input
        class="password-input"
        @input="_input"
        @keyup="_keyup"
        :type="!password ?'number':'text'":ref="`passwordIndex${index}`":value="!password ? code[index] : passwordViewCode[index]":maxlength="1"v-max-length="{password, mark}"
      />
    </div>
    <div class="mantle" @click="setFocus"></div>
  </div>
</template>
<script>
export default {data() {
    return {
      code: "",
      passwordViewCode: "",
    };
  },
  props: {
    // 明码数量
    length: {
      type: Number,
      default: 6,
    },
    // 是否展现明文
    password: {
      type: Boolean,
      default() {return false;},
    },
    // 加密字符
    mark: {
      type: String,
      default() {return "●";},
    },
    // 格子间距
    gutter: {
      type: String,
      default() {return "0";},
    },
  },
  directives: {
    /**
     * 自定义指令 最大数量
     */
    maxLength: {bind(el, { value}) {el.oninput = () => {
          let str = el.value;
          if (el.value.length > 1) {if (str.length > 1) {el.value = value.password ? value.mark : str.charAt(0);
            } else {el.value = str.charAt(0);
            }
          }
        };
      },
    },
  },
  methods: {
    /**
     * 焦点赋值
     */
    setFocus() {
      let _length = this.code.length;
      if (_length < this.length) {this.$refs[`passwordIndex${_length}`][0].focus();} else {this.$refs[`passwordIndex${_length - 1}`][0].focus();}
    },
    /**
     * 输出
     */
    _input(e) {if (e != null) {
        let str = e.data;
        if (/[^\d]/g.test(str)) {
          str = "";
          this.$refs[`passwordIndex0`][0].value = str;
        }
        if (/^[0-9]+$/.test(str)) {if (this.code.length < this.length) {
            this.code += str;
            this.passwordViewCode += this.mark;
            this.setFocus();}
          if (this.code.length == this.length) {this.$emit("change", this.code);
          }
        }
      }
    },
    /**
     * 删除
     */
    _keyup(e) {if (e.keyCode == 8) {
        let str = this.code;
        this.code = str.substr(0, str.length - 1);
        let password_str = this.passwordViewCode;
        this.passwordViewCode = password_str.substr(0, password_str.length - 1);
        this.setFocus();}
    },
    /**
     * 重置数据
     */
    resetData() {
      this.code = "";
      this.passwordViewCode = "";
    },
  },
};
</script>
<style lang="scss" scoped>
.password-number {
  height: 40px;
  width: 400px;
  border: 1px solid #ddd;
  display: flex;
  position: relative;
  &.gutter {border: 0;}
  .mantle {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    cursor: pointer;
  }
  .password-item {
    flex: 1;
    position: relative;
    &::after {
      content: "";
      display: block;
      width: 1px;
      height: 30px;
      background-color: #eee;
      position: absolute;
      top: 50%;
      transform: translateY(-50%);
      left: 0;
    }
    &:nth-child(1) {
      &::after {display: none;}
    }
    &.gutter {
      background-color: #eee;
      width: 40px;
      &::after {display: none;}
    }
    .password-input {
      width: 100%;
      height: 100%;
      text-align: center;
      display: flex;
      align-items: center;
      justify-content: center;
      background: none;
      border: 0;
    }
  }
}
</style>
正文完
 0