vue實現(xiàn)數(shù)字+英文字母組合鍵盤功能
完整代碼
<template>
<div class="login">
<div @click="setFileClick">歡迎使用員工自助終端</div>
<el-dialog title="初始化設置文件打印消耗品配置密碼" :visible.sync="dialogSetFile" width="600px">
<el-form :model="fileForm" ref="fileForm" status-icon label-width="100px">
<el-form-item label="密碼" prop="password">
<el-input type="password" v-model="fileForm.password" show-password @focus="ifWritePopUp = true"></el-input>
</el-form-item>
<div class="screen-sign-mid" style="display: none;">
<div class="screen-sign-mid-inner">
<input class="self-el-input" type="text" v-model="password" ref="passwordInput" />
<button class="self-el-button" type="button" @click.stop="checkIn()">確認</button>
</div>
</div>
<!-- 鍵盤組件開始 -->
<div class="keyboard-wrap" v-show="ifWritePopUp">
<div class="key-group-item" v-for="(keyItem, index) in keyList" :key="index">
<div class="key-item" :style="item.type == 'letter' ? '' : 'width:135px;'" v-for="(item, index) in keyItem" :key="index" :data-type="item.type" @click.stop="keyboardClick">
<span class="vertical-center">{{ item.text }}</span>
</div>
</div>
</div>
<div style="text-align: center;">
<el-button type="primary" @click="submitForm" icon="el-icon-check">提交</el-button>
<el-button @click="resetForm" icon="el-icon-delete">重置</el-button>
</div>
</el-form>
</el-dialog>
</div>
</template>
<script>
import { queryInitializeFile, initPassword } from "@/api/setFile";
export default {
data() {
return {
clickCount: 0, //點擊次數(shù)
dialogSetFile: false, //初始化文件配置
ifInitialize: '', //是否初始化
fileForm: {
password: '',
},
ifWritePopUp: false,
password: "", //鍵盤輸入內(nèi)容
keyList: [
// 鍵盤布局
[{ text: "1",type: "digit"},{ text: "2",type: "digit"},
{ text: "3",type: "digit"},{ text: "4",type: "digit"},
{ text: "5",type: "digit"},{ text: "6",type: "digit"},
{ text: "7",type: "digit"},{ text: "8",type: "digit"},
{ text: "9",type: "digit"},{ text: "0",type: "digit"}],
[{text: "Q",type: "digit"},{text: "W",type: "digit"},
{text: "E",type: "digit"},{text: "R",type: "digit"},
{text: "T",type: "digit"},{text: "Y",type: "digit"},
{text: "U",type: "digit"},{text: "I",type: "digit"},
{text: "O",type: "digit"},{text: "P",type: "digit"}],
[{text: "A",type: "digit"},{text: "S",type: "digit"},
{text: "D",type: "digit"},{text: "F",type: "digit"},
{text: "G",type: "digit"},{text: "H",type: "digit"},
{text: "J",type: "digit"},{text: "K",type: "digit"},
{text: "L",type: "digit"}],
[{text: "Z",type: "digit"},{text: "X",type: "digit"},
{text: "C",type: "digit"},{text: "V",type: "digit"},
{text: "B",type: "digit"},{text: "N",type: "digit"},
{text: "M",type: "digit"}],
[{text: "回刪",type: "delete"},],
],
};
},
methods: {
// 處理鍵盤事件
keyboardClick(event) {
let text = event.currentTarget.innerText;
let type = event.currentTarget.getAttribute("data-type");
switch (type) {
case "digit":
this.password += text;
this.fileForm.password = this.password;
break;
case "delete":
this.password = this.password.substr(0, this.password.length - 1);
this.fileForm.password = this.password
break;
}
this.$refs.passwordInput.focus();
},
checkIn() {
if (this.password == "") {
this.$refs["passwordInput"].focus();
return;
}
this.password = "";
this.ifWritePopUp = false
},
//點擊事件
setFileClick() {
this.clickCount += 1; // 每次點擊增加計數(shù)器的值
this.fileForm = {}
if (this.clickCount === 5) {
//檢查是否要初始化設置文件打印消耗品配置的密碼
queryInitializeFile().then((res) => {
if (res && res.code === 200) {
this.clickCount = 0
this.ifInitialize = res.data
//true初始化設置文件打印消耗品配置的密碼
if (this.ifInitialize === true) {
this.dialogSetFile = true
this.password = ""
this.ifWritePopUp = true
}
} else {
this.$message.error(res.msg);
}
})
}
},
//提交按鈕
submitForm() {
if (!this.fileForm.password) {
this.$message.warning('請輸入密碼');
return;
}
// 密碼正則表達式
const passwordRegex = /^(?=.*[a-zA-Z])(?=.*\d)[a-zA-Z\d]{6,8}$/;
if (!passwordRegex.test(this.fileForm.password)) {
this.$message.warning('密碼由數(shù)字和英文字母組成,且長度為6~8位');
return;
}
//初始化設置文件打印消耗品配置密碼
initPassword(this.fileForm.password).then((res) => {
if (res && res.code == 200) {
this.clickCount = 0
this.$message.success(res.msg);
this.dialogSetFile = false
} else {
this.$message.error(res.msg);
}
});
},
//密碼清空重置
resetForm() {
this.password = ''
this.fileForm = {}
},
},
};
</script>
<style lang="less" scoped>
.login {
padding-top: 80px;
}
.screen-sign-mid {
position: relative;
width: 100%;
height: 80px;
padding: 3px;
box-sizing: border-box;
background-color: #eee;
color: #34592d;
}
.screen-sign-mid .screen-sign-mid-inner {
width: 100%;
height: 100%;
position: relative;
box-sizing: border-box;
}
.self-el-input {
display: inline-block;
width: 78%;
height: 80%;
padding: 0 100px 0 15px;
font-size: 26px;
color: #000;
border: 2px solid #35b9ff;
border-radius: 10px;
-webkit-appearance: none;
background-color: #eee;
background-image: none;
-webkit-box-sizing: border-box;
box-sizing: border-box;
-webkit-transition: border-color .2s cubic-bezier(.645, .045, .355, 1);
transition: border-color .2s cubic-bezier(.645, .045, .355, 1);
outline: 0;
}
.self-el-button {
display: inline-block;
position: absolute;
top: 2px;
right: 2px;
width: 100px;
height: 56px;
margin: 0;
font-size: 22px;
border-radius: 10px;
border: 2px solid #35b9ff;
color: #fff;
background-color: #35b9ff;
}
.keyboard-wrap {
width: 100%;
box-sizing: border-box;
}
.keyboard-wrap .key-group-item {
width: 100%;
height: auto;
text-align: center;
}
.key-group-item .key-item {
display: inline-block;
position: relative;
width: 50px;
height: 50px;
line-height: 50px;
margin: 0 2px 8px 2px;
color: #000;
font-size: 20px;
box-sizing: border-box;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 15px;
background-color: #dedede;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
cursor: pointer;
}
</style>代碼詳解
1.鍵盤界面是根據(jù)keyList數(shù)組中定義的內(nèi)容動態(tài)生成的。
- 我在外層使用了v-show="ifWritePopUp"來控制鍵盤界面的顯示與隱藏。
- 通過v-for="(keyItem, index) in keyList" :key="index"遍歷keyList數(shù)組,生成多個key-group-item,每個key-group-item代表一行鍵位。
- 在每個key-group-item內(nèi)部,再次通過v-for="(item, index) in keyItem" :key="index"遍歷keyItem數(shù)組,生成具體的按鍵元素。
- 每個按鍵元素使用:style屬性來動態(tài)設置樣式,根據(jù)item.type的值來確定是否為字母鍵位,從而動態(tài)設置寬度。
- 通過:data-type="item.type" @click.stop="keyboardClick"將按鍵的類型和點擊事件綁定到對應的DOM元素上。

上圖所示方法,主要用于處理用戶在虛擬鍵盤上的點擊操作,動態(tài)更新密碼輸入框中的內(nèi)容,并保持輸入焦點的流暢切換
- 當用戶點擊鍵盤上的按鍵時,觸發(fā)keyboardClick方法,同時將事件對象event作為參數(shù)傳入
- 通過event.currentTarget獲取被點擊的按鍵元素,然后分別獲取該按鍵的文本內(nèi)容和數(shù)據(jù)類型;
- 根據(jù)被點擊的按鍵的數(shù)據(jù)類型,判斷是字母鍵還是刪除鍵,并進行相應的邏輯處理:
- 若是字母鍵,則將該字母添加到密碼輸入框中,并更新fileForm.password的值;
若是刪除鍵,則從密碼輸入框中刪除最后一個字符,并更新fileForm.password的值
- 最后,調(diào)用this.$refs.passwordInput.focus()將焦點重新定位到密碼輸入框,以便繼續(xù)執(zhí)行輸入或刪除操作。

我在這邊設置了CSS樣式屬性
display: none;可以使元素不顯示在頁面上(即隱藏)。這意味著該元素將不會占據(jù)任何空間,并且無法通過直接的交互方式與用戶進行互動。
@click.stop是Vue中阻止事件冒泡的指令(防止該事件繼續(xù)向上傳播,避免重復執(zhí)行相同的事件處理函數(shù))。它可以通過在事件處理函數(shù)中使用event.stopPropagation()方法來停止事件向父級元素傳播。簡單來說,當用戶在元素上點擊鼠標時,會觸發(fā)該元素的點擊事件,并向父級元素依次傳播。如果在某個父級元素上綁定了相同類型的事件處理函數(shù),則該函數(shù)也會被調(diào)用。
數(shù)字+英文字母鍵盤效果圖展示
未設置style="display: none;",隱藏輸入框和確認按鈕的效果圖



OVER!!!
到此這篇關于vue中實現(xiàn)數(shù)字+英文字母組合鍵盤的文章就介紹到這了,更多相關vue數(shù)字鍵盤內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vue3+Echarts實現(xiàn)立體柱狀圖的示例代碼
本文介紹了使用Echarts實現(xiàn)立體柱狀圖的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2025-07-07
vue項目中el-table的@row-click事件與行內(nèi)點擊事件沖突問題及解決
文章描述了在點擊表格行內(nèi)按鈕時觸發(fā)行點擊事件的問題,分析了事件冒泡的原因,并提出了使用.native.stop來阻止冒泡的解決方案2026-04-04
Pinia入門學習之實現(xiàn)簡單的用戶狀態(tài)管理
Vue3雖然相對于Vue2很多東西都變了,但是核心的東西還是沒有變,比如說狀態(tài)管理、路由等,再Vue3中尤大神推薦我們使用pinia來實現(xiàn)狀態(tài)管理,他也說pinia就是Vuex的新版本,這篇文章主要給大家介紹了關于Pinia入門學習之實現(xiàn)簡單的用戶狀態(tài)管理的相關資料,需要的朋友可以參考下2022-11-11
vue中內(nèi)網(wǎng)/局域網(wǎng)/離線的情況下使用及建立項目方式
這篇文章主要介紹了vue中內(nèi)網(wǎng)/局域網(wǎng)/離線的情況下使用及建立項目方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04

