共计 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>
正文完