一、完整 代码展示
<template><div class="login"><div class="login-content"><img class="img" src="../../assets/image/loginPhone.png" /><el-card class="box-card"><div slot="header" class="clearfix"><span>手机号登录</span></div><div class="text-content"><el-form :model="ruleForm" label-width="80px"><el-form-item label="手机号" class="keyboard-wrapper"><el-input placeholder="请输入手机号" v-model.sync="ruleForm.tel" clearable@focus="viewShow('tel')" onfocus="this.blur()" @input="handleInputTel" maxlength="11" show-word-limit></el-input></el-form-item><el-form-item label="验证码" class="keyboard-wrapper"><el-input placeholder="请输入验证码" v-model.sync="ruleForm.code" @focus="viewShow('code')"onfocus="this.blur()" @input="handleInput" clearable><template slot="append"><el-button style="font-size: 22px;" :disabled="Boolean(timer)" @click="getCode">{{ timer ? time + "S" : "获取" }}</el-button></template></el-input><!-- 手机号键盘 --><div class="keyboard" v-if="telShow"><div class="num"><table><tr><td @click="changeTel(1)" :class="[tel === 1 ? 'tel' : '']">1</td><td @click="changeTel(2)" :class="[tel === 2 ? 'tel' : '']">2</td><td @click="changeTel(3)" :class="[tel === 3 ? 'tel' : '']">3</td><td rowspan="2" class="delTel" @click="delTel">×</td></tr><tr><td @click="changeTel(4)" :class="[tel === 4 ? 'tel' : '']">4</td><td @click="changeTel(5)" :class="[tel === 5 ? 'tel' : '']">5</td><td @click="changeTel(6)" :class="[tel === 6 ? 'tel' : '']">6</td></tr><tr><td @click="changeTel(7)" :class="[tel === 7 ? 'tel' : '']">7</td><td @click="changeTel(8)" :class="[tel === 8 ? 'tel' : '']">8</td><td @click="changeTel(9)" :class="[tel === 9 ? 'tel' : '']">9</td><td rowspan="2" class="comfirmTel" @click="comfirmTel">确定</td></tr><tr><td @click="changeTel(0)" colspan="3" :class="[tel === 0 ? 'tel' : '']">0</td></tr></table></div></div><!-- 验证码鍵盤 --><div class="keyboard" v-if="show"><div class="num"><table><tr><td @click="change(1)" :class="[code === 1 ? 'code' : '']">1</td><td @click="change(2)" :class="[code === 2 ? 'code' : '']">2</td><td @click="change(3)" :class="[code === 3 ? 'code' : '']">3</td><td rowspan="2" class="del" @click="del">×</td></tr><tr><td @click="change(4)" :class="[code === 4 ? 'code' : '']">4</td><td @click="change(5)" :class="[code === 5 ? 'code' : '']">5</td><td @click="change(6)" :class="[code === 6 ? 'code' : '']">6</td></tr><tr><td @click="change(7)" :class="[code === 7 ? 'code' : '']">7</td><td @click="change(8)" :class="[code === 8 ? 'code' : '']">8</td><td @click="change(9)" :class="[code === 9 ? 'code' : '']">9</td><td rowspan="2" class="comfirm" @click="comfirm">确定</td></tr><tr><td @click="change(0)" colspan="3" :class="[code === 0 ? 'code' : '']">0</td></tr></table></div></div></el-form-item></el-form></div></el-card><div style="text-align: center;margin-left: 10px;"><el-button type="primary" :loading="loading" :disabled="!ruleForm.tel || !ruleForm.code"@click="linkToPage">登录</el-button></div></div></div>
</template>
<script>import storage from "store";import { useLogin, getCode } from "@/api/index.js";export default {data() {return {time: 60,ruleForm: {tel: "",code: "",},show: false,telShow: false,NUM: "",NUMTEL: "",result: [],resultTel: [],tel: '',code: '',timer: null,loading: false,};},computed: {// 统计数量num: function() {return this.result.join("");},// 统计数量numtel: function() {return this.resultTel.join("");},},methods: {//登录linkToPage() {this.loading = true;useLogin(this.ruleForm).then((res) => {if (res.code == 200) {storage.set("Access-Token", res.data.token); // 正常请求tokenstorage.set("User-Info", JSON.stringify(res.data)); // 正常请求tokensetTimeout(() => {this.$router.push("/index")}, 2000);} else {this.$message.error(res.msg);}}).finally(() => {this.loading = false;});},//获取验证码getCode() {if (!this.ruleForm.tel) return;// 检查手机号格式是否正确const phoneNumberRegex = /^1[3456789]\d{9}$/;if (!phoneNumberRegex.test(this.ruleForm.tel)) {this.$message.warning('手机号格式不正确,请重新输入!');return;}getCode(this.ruleForm).then((res) => {if (res.code === 200) {this.$message.success(res.msg);this.timer = setInterval(() => {if (this.time == 0) {clearInterval(this.timer);this.timer = null;this.time = 60;} else {this.time--;}}, 1000);} else {this.$message.error(res.msg);}});},//展示数字键盘viewShow(type) {if (type === 'tel') {this.telShow = !this.telShowthis.show = false} else {this.show = !this.showthis.telShow = false}},handleInput() {if (this.ruleForm.code.length >= 6) return;},//获取选中的数字 验证码change(val, $event) {//设置验证码的长度if (this.ruleForm.code.length >= 6) return;this.ruleForm.code += String(val)if (this.result.length === 0) {return false;} else {this.result.push(this.ruleForm.code);this.NUM = this.result.join("");}},//验证码刪除del() {this.ruleForm.code = this.ruleForm.code.slice(0, -1)this.NUM = this.result.join("");this.$emit("del", this.NUM);},//验证码確認按鈕comfirm() {this.$emit("comfirm", this.NUM);this.show = false;},//获取选中的数字 手机号changeTel(val, $event) {//设置验证码的长度if (this.ruleForm.tel.length >= 11) return;this.ruleForm.tel += String(val)if (this.resultTel.length === 0) {return false;} else {this.resultTel.push(this.ruleForm.tel);this.NUMTEL = this.resultTel.join("");}},handleInputTel() {if (this.ruleForm.tel.length >= 11) return;},//刪除 手机号delTel() {this.ruleForm.tel = this.ruleForm.tel.slice(0, -1)this.NUMTEL = this.resultTel.join("");this.$emit("delTel", this.NUMTEL);},//確認按鈕 手机号comfirmTel() {this.$emit("comfirmTel", this.NUMTEL);this.telShow = false;},},};
</script>
二、方法详解
1、数据详解:
ruleForm
对象包含了手机号和验证码两个属性;show
和telShow
分别表示验证码键盘和手机号键盘是否显示状态;NUM
和NUMTEL表示
存储选中的验证码和手机号;result
和resultTel
表示用于存储选中的验证码和手机号的数组;tel
和code
表示当前选中的手机号和验证码的数字;timer
用于控制获取验证码按钮的倒计时;loading
表示登录按钮的加载状态。
2、计算属性详解:
num:
用于将选中的验证码数字拼接为字符串;numtel:
用于将选中的手机号数字拼接为字符串。
3、方法详解:
viewShow
方法用于切换显示手机号键盘或验证码键盘。handleInput
方法用于限制验证码输入框的长度不超过6位。change
方法用于获取选中的验证码数字,并将其拼接到ruleForm.code
中。del
方法用于删除最后一个输入的验证码数字。comfirm
方法用于确认验证码的输入,同时关闭验证码键盘。- 手机号键盘相关方法同验证码键盘类似。
4、方法注释:
push():
用于向数组末尾添加一个或多个元素
slice():
方法接收两个参数起始位置和结束位置(不含结束位置)
this.ruleForm.tel.slice(0, -1)
表示获取this.ruleForm.tel
的子数组,从索引0开始,到倒数第一个元素(不含倒数第一个元素)结束。简单来说,它删除了this.ruleForm.tel
的最后一个字符,并将剩余的部分赋值给this.ruleForm.tel
。
三、Css样式
<style lang="less" scoped>.login {padding-top: 80px;}.login-title {position: fixed;left: 0;top: 0;display: flex;align-items: center;justify-content: space-between;width: calc(100% - 80px);height: 160px;padding: 0 40px;background-color: @theme-color;color: #fff;font-size: 38px;font-weight: bold;}.login-content {display: flex;justify-content: center;align-items: center;padding: 200px;}.clearfix {text-align: center;color: #00aaff;font-size: 26px;}.box-card {height: 520px;width: 480px;border-radius: 20px;}.keyboard-wrapper {user-select: none;input {width: 100%;height: 50px;font-size: 26px;}.keyboard {position: fixed;margin-top: 10px;width: 60%;.num {table {width: 32%;border: 1px solid #ccc;border-collapse: collapse;background: #fff;td {height: 60px;vertical-align: middle;color: #333;font-size: 20px;border: 1px solid #ccc;text-align: center;}td.active {background: #ccc;}.del {background: #eee;}.comfirm {font-size: 16px;width: 80px;background: #62c7eb;color: #fff;}.delTel {background: #eee;}.comfirmTel {font-size: 16px;width: 80px;background: #118eeb;color: #fff;}}}}}
</style>
手机号数字键盘效果图
验证码数字键盘效果图