1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
| <template> <div class="security-code-wrap"> <label :for="`code-${uuid}`"> <ul :class="`${theme}-container security-code-container`"> <li class="field-wrap" v-for="(item, index) in length" :key="index"> <i class="char-field">{{value[index] || placeholder}}</i> </li> </ul> </label> <input ref="input" class="input-code" @keyup="handleInput($event)" v-model="value" :id="`code-${uuid}`" :name="`code-${uuid}`" type="tel" :maxlength="length" autocorrect="off" autocomplete="off" autocapitalize="off"> </div> </template>
<script> export default { name: 'SecurityCode', props: { length: { type: Number, default: 4 }, placeholder: { type: String, default: '-' }, theme: { type: String, default: 'block' } }, data () { return { value: '' } }, computed: { uuid () { return Math.random().toString(36).substring(3, 8) } }, methods: { hideKeyboard () { document.activeElement.blur() this.$refs.input.blur() }, handleSubmit () { this.$emit('input', this.value) }, handleInput (e) { if (e.target.value.length >= this.length) { this.hideKeyboard() } this.handleSubmit() } } } </script>
<style scoped lang="less"> .security-code-wrap { display: flex; align-items: center; justify-content: center; }
.security-code-container { margin: 0; padding: 0; display: flex; .field-wrap { list-style: none; display: block; height: 40px; width: 40px; line-height: 40px; font-size: 16px; .char-field { font-style: normal; } } }
.block-container { justify-content: center; .field-wrap { background-color: #fff; margin: 2px; color: #000; } }
.line-container { position: relative; background-color: #fff; &:after { box-sizing: border-box; content: ""; width: 200%; height: 200%; transform: scale(.5); position: absolute; border: 1px solid #d9d9d9; top: 0; left: 0; transform-origin: 0 0; border-radius: 4px; } .field-wrap { flex: 1; position: relative; &:not(:last-child):after { content: ""; width: 1px; height: 50%; position: absolute; right: 0; top: 25%; background-color: #d9d9d9; transform: scaleX(.5); } } }
.input-code { position: absolute; left: -9999px; top: -9999px; }
</style>
|