How to implement a 6-digit payment password input box in vue3
Specific requirements: In the operation column of the customer information form, click the Modify Payment Password button, and it will jump to the 6-digit payment password input box component page. At the same time, the input box is required to display cipher text, cannot be edited, cannot be rolled back, and is displayed immediately; when it reaches 6 digits, it will automatically enter to confirm the payment password; when the confirmation payment password reaches 6 digits, it will automatically check the consistency of the two passwords entered, and display OK button. This function is intended to be used in banks where customers use devices to enter passwords. The tellers cannot see the passwords, but the tellers can prompt them.
Specific questions: 1. How to display cipher text, and only 1 digit can be entered in each box; 2. How to make the input box non-editable and non-returnable; 3. How to check the consistency of entering passwords twice; 4. What to do if your business needs to restrict keyboard keys.
1. Code Overview
The code to implement the 6-digit payment password input box component is as follows, Copy it and use it directly!
<template> <div > <!-- 密码输入框 --> <div class="input-box" > <!-- 输入密码 --> <div >{{ "输入密码" }}</div> <div class="input-content" @keyup="keyup" @input="inputEvent"> <input max="9" min="0" maxlength="1" data-index="0" v-model.number="state.input[0]" type="password" ref="firstinput" :disabled="state.disabledInput[0]" /> <input max="9" min="0" maxlength="1" data-index="1" v-model.number="state.input[1]" type="password" :disabled="state.disabledInput[1]" /> <input max="9" min="0" maxlength="1" data-index="2" v-model.number="state.input[2]" type="password" :disabled="state.disabledInput[2]" /> <input max="9" min="0" maxlength="1" data-index="3" v-model.number="state.input[3]" type="password" :disabled="state.disabledInput[3]" /> <input max="9" min="0" maxlength="1" data-index="4" v-model.number="state.input[4]" type="password" :disabled="state.disabledInput[4]" /> <input max="9" min="0" maxlength="1" data-index="5" v-model.number="state.input[5]" type="password" :disabled="state.disabledInput[5]" /> </div> <!-- 确认密码 --> <div >{{ "确认密码" }}</div> <div class="input-content" @keyup="confirmKeyUp" @input="confirmInputEvent"> <input max="9" min="0" maxlength="1" data-index="0" v-model.number="state.confirmInput[0]" type="password" ref="confirmfirstinput" :disabled="state.disabledConfirmInput[0]" /> <input max="9" min="0" maxlength="1" data-index="1" v-model.number="state.confirmInput[1]" type="password" :disabled="state.disabledConfirmInput[1]" /> <input max="9" min="0" maxlength="1" data-index="2" v-model.number="state.confirmInput[2]" type="password" :disabled="state.disabledConfirmInput[2]" /> <input max="9" min="0" maxlength="1" data-index="3" v-model.number="state.confirmInput[3]" type="password" :disabled="state.disabledConfirmInput[3]" /> <input max="9" min="0" maxlength="1" data-index="4" v-model.number="state.confirmInput[4]" type="password" :disabled="state.disabledConfirmInput[4]" /> <input max="9" min="0" maxlength="1" data-index="5" v-model.number="state.confirmInput[5]" type="password" :disabled="state.disabledConfirmInput[5]" /> </div> </div> <!-- 按钮 --> <div > <el-button type="info" :disabled="state.disabledConfirm" @click="reConfirm" :class="[state.disabledConfirm ? 'noActive' : 'active']">{{ "确定" }}</el-button> <el-button type="warning" @click="reset">{{ "重新输入" }}</el-button> </div> <!-- 提示区 --> <div > <p>{{ state.tipContent }}</p> </div> </div> </template> <script lang="ts" setup> import { nextTick, reactive, ref, onMounted } from "vue"; import { ElMessage, ElMessageBox } from 'element-plus' const state = reactive({ // 输入数组 input: ["", "", "", "", "", ""], // 确认输入数组 confirmInput: ["", "", "", "", "", ""], // 存放粘贴进来的数字 pasteResult: [], confirmPasteResult: [], // 一上来禁用确定按钮 disabledConfirm: true, // 输入框是否禁用 disabledInput: [false, false, false, false, false, false], disabledConfirmInput: [false, false, false, false, false, false], // 提示内容 tipContent: "请告知客户输入6位数字密码,输入完毕后,点击回车确认。" }) // 获取第一个元素的ref const firstinput = ref() const confirmfirstinput = ref() // 页面一加载就使第一个框聚焦 onMounted(() => { // 等待dom渲染完成,在执行focus,否则无法获取到焦点 nextTick(() => { firstinput.value.focus(); }); }) // @input的处理方法 // 解决一个输入框输入多个字符 const inputEvent = (e) => { var index = e.target.dataset.index * 1; var el = e.target; // 限制只能输入数字 el.value = el.value.replace(/[^\d]/g, ""); if (el.value.length >= 1) { // 密文显示、不可编辑、不可回退、即时显示 state.disabledInput[index] = true; if (el.nextElementSibling) { el.nextElementSibling.focus(); } } // 到达6位数,自动进入确认支付密码 if (!el.nextElementSibling) { confirmfirstinput.value.focus(); state.tipContent = "请告知客户再次输入6位数字密码,输入完毕后,点击回车确认。"; } } // @keydown的处理方法,根据业务需要添加 // 此示例没有使用 const keydown = (e) => { var index = e.target.dataset.index * 1; var el = e.target; // 回退键 if (e.key === 'Backspace') { if (state.input[index].length > 0) { state.input[index] = '' } else { if (el.previousElementSibling) { el.previousElementSibling.focus() state.input[index - 1] = '' } } } // 删除键 else if (e.key === 'Delete') { if (state.input[index].length > 0) { state.input[index] = '' } else { if (el.nextElementSibling) { state.input[1] = '' } } if (el.nextElementSibling) { el.nextElementSibling.focus() } } // 左键 else if (e.key === 'ArrowLeft') { if (el.previousElementSibling) { el.previousElementSibling.focus() } } // 右键 else if (e.key === 'ArrowRight') { if (el.nextElementSibling) { el.nextElementSibling.focus() } } // 上键 else if (e.key === 'ArrowUp') { if (Number(state.input[index]) * 1 < 9) { state.input[index] = (Number(state.input[index]) * 1 + 1).toString() } } // 下键 else if (e.key === 'ArrowDown') { if (Number(state.input[index]) * 1 > 0) { state.input[index] = (Number(state.input[index]) * 1 - 1).toString() } } } // @keyup的处理方法 const keyup = (e) => { var index = e.target.dataset.index * 1; // 如果为最后一个框,则输入框全部失焦 if (index === 5) { if (state.input.join("").length === 6) { document.activeElement.blur(); } } } // @input的处理方法 // 解决一个输入框输入多个字符 const confirmInputEvent = (e) => { var index = e.target.dataset.index * 1; var el = e.target; if (el.value.length >= 1) { // 密文显示、不可编辑、不可回退、即时显示 state.disabledConfirmInput[index] = true; if (el.nextElementSibling) { el.nextElementSibling.focus(); } } // 到达6位数,自动检验两次输入密码的一致性 if (!el.nextElementSibling) { // 一一比较元素值,有一个不相等就不等 for (let i = 0; i < state.input.length; i++) { if (state.input[i] !== state.confirmInput[i]) { state.tipContent = "请告知客户两次密码输入不一致,柜员点击重新输入,清空密码后请告知客户重新输入。"; return; } } state.tipContent = "密码合规,点击确定按钮进行修改。"; // 确定按钮变为可用 state.disabledConfirm = false; } } // @keydown的处理方法,根据业务需要添加 // 此示例没有使用 const confirmKeydown = (e) => { var index = e.target.dataset.index * 1; var el = e.target; // 回退键 if (e.key === 'Backspace') { if (state.confirmInput[index].length > 0) { state.confirmInput[index] = '' } else { if (el.previousElementSibling) { el.previousElementSibling.focus() state.confirmInput[index - 1] = '' } } } // 删除键 else if (e.key === 'Delete') { if (state.confirmInput[index].length > 0) { state.confirmInput[index] = '' } else { if (el.nextElementSibling) { state.confirmInput[1] = '' } } if (el.nextElementSibling) { el.nextElementSibling.focus() } } // 左键 else if (e.key === 'ArrowLeft') { if (el.previousElementSibling) { el.previousElementSibling.focus() } } // 右键 else if (e.key === 'ArrowRight') { if (el.nextElementSibling) { el.nextElementSibling.focus() } } // 上键 else if (e.key === 'ArrowUp') { if (Number(state.confirmInput[index]) * 1 < 9) { state.confirmInput[index] = (Number(state.confirmInput[index]) * 1 + 1).toString() } } // 下键 else if (e.key === 'ArrowDown') { if (Number(state.confirmInput[index]) * 1 > 0) { state.confirmInput[index] = (Number(state.confirmInput[index]) * 1 - 1).toString() } } } // @keyup的处理方法 const confirmKeyUp = (e) => { var index = e.target.dataset.index * 1; // 如果为最后一个框,则输入框全部失焦 if (index === 5) { if (state.confirmInput.join("").length === 6) { document.activeElement.blur(); } } } // 重新输入 const reset = () => { state.disabledConfirm = true; state.tipContent = "请告知客户输入6位数字密码,输入完毕后,点击回车确认。"; state.input = ["", "", "", "", "", ""]; state.confirmInput = ["", "", "", "", "", ""]; state.disabledInput = [false, false, false, false, false, false]; state.disabledConfirmInput = [false, false, false, false, false, false]; // 等待dom渲染完成,在执行focus,否则无法获取到焦点 nextTick(() => { firstinput.value.focus(); }); } // 确认修改 const reConfirm = () => { ElMessageBox.confirm( '是否确定修改?', '温馨提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning', } ) .then(() => { // 此处调修改支付密码接口 ElMessage({ type: 'success', message: '修改成功!', }) }) .catch(() => { ElMessage({ type: 'info', message: '已取消修改!', }) }) } </script> <style lang="scss" scoped> .input-box { .input-content { width: 512px; height: 60px; display: flex; align-items: center; justify-content: space-between; input { color: inherit; font-family: inherit; border: 0; outline: 0; border-bottom: 1px solid #919191; height: 60px; width: 60px; font-size: 44px; text-align: center; } } input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { appearance: none; margin: 0; } } .noActive { color: #fff !important; border-width: 0px !important; background-color: #ccc !important; } .active { color: #fff !important; border-width: 0px !important; background-color: #67c23a !important; } </style>
2. Problem analysis
1. Question: How to display cipher text and only 1 digit can be entered in each box?
If you want to enter cipher text, you only need to set the type of the input box to "password". To realize that each box can only input 1 digit, the effect of using only the maxlength attribute of the input box is not perfect, and there may be situations where it cannot be restricted. You need to judge the length of the current element value in the @input event. If it is greater than If equal to 1, use nextElementSibling.focus() to focus the cursor on the next sibling element.
2. Question: How to make the input box non-editable and non-returnable?
Answer: The disabled attribute of the input box is used. In the @input event, the disabled attribute of the current input element can be changed to true. In order to facilitate subsequent acquisition and modification, we store the disabled attribute value of the input box in an array.
3. Question: How to check the consistency of the password entered twice?
Answer: The simplest for loop is used to traverse the input password array and confirmation password array, compare their element values one by one, if one is not equal, then it is not equal, and end the execution of the entire function through return;.
4. Question: What should I do if my business needs to restrict keyboard keys?
Answer: You can add @keydown or @keyup events to the input box, and perform some business processing on different keys by judging the key inside the callback.
The above is the detailed content of How to implement a 6-digit payment password input box in vue3. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



tinymce is a fully functional rich text editor plug-in, but introducing tinymce into vue is not as smooth as other Vue rich text plug-ins. tinymce itself is not suitable for Vue, and @tinymce/tinymce-vue needs to be introduced, and It is a foreign rich text plug-in and has not passed the Chinese version. You need to download the translation package from its official website (you may need to bypass the firewall). 1. Install related dependencies npminstalltinymce-Snpminstall@tinymce/tinymce-vue-S2. Download the Chinese package 3. Introduce the skin and Chinese package. Create a new tinymce folder in the project public folder and download the

vue3+vite:src uses require to dynamically import images and error reports and solutions. vue3+vite dynamically imports multiple images. If vue3 is using typescript development, require will introduce image errors. requireisnotdefined cannot be used like vue2 such as imgUrl:require(' .../assets/test.png') is imported because typescript does not support require, so import is used. Here is how to solve it: use awaitimport

To achieve partial refresh of the page, we only need to implement the re-rendering of the local component (dom). In Vue, the easiest way to achieve this effect is to use the v-if directive. In Vue2, in addition to using the v-if instruction to re-render the local dom, we can also create a new blank component. When we need to refresh the local page, jump to this blank component page, and then jump back in the beforeRouteEnter guard in the blank component. original page. As shown in the figure below, how to click the refresh button in Vue3.X to reload the DOM within the red box and display the corresponding loading status. Since the guard in the component in the scriptsetup syntax in Vue3.X only has o

Vue implements the blog front-end and needs to implement markdown parsing. If there is code, it needs to implement code highlighting. There are many markdown parsing libraries for Vue, such as markdown-it, vue-markdown-loader, marked, vue-markdown, etc. These libraries are all very similar. Marked is used here, and highlight.js is used as the code highlighting library. The specific implementation steps are as follows: 1. Install dependent libraries. Open the command window under the vue project and enter the following command npminstallmarked-save//marked to convert markdown into htmlnpmins

After the vue3 project is packaged and published to the server, the access page displays blank 1. The publicPath in the vue.config.js file is processed as follows: const{defineConfig}=require('@vue/cli-service') module.exports=defineConfig({publicPath :process.env.NODE_ENV==='production'?'./':'/&

The final effect is to install the VueCropper component yarnaddvue-cropper@next. The above installation value is for Vue3. If it is Vue2 or you want to use other methods to reference, please visit its official npm address: official tutorial. It is also very simple to reference and use it in a component. You only need to introduce the corresponding component and its style file. I do not reference it globally here, but only introduce import{userInfoByRequest}from'../js/api' in my component file. import{VueCropper}from'vue-cropper&

Preface Whether it is vue or react, when we encounter multiple repeated codes, we will think about how to reuse these codes instead of filling a file with a bunch of redundant codes. In fact, both vue and react can achieve reuse by extracting components, but if you encounter some small code fragments and you don’t want to extract another file, in comparison, react can be used in the same Declare the corresponding widget in the file, or implement it through renderfunction, such as: constDemo:FC=({msg})=>{returndemomsgis{msg}}constApp:FC=()=>{return(

vue3+ts+axios+pinia realizes senseless refresh 1. First download aiXos and pinianpmipinia in the project--savenpminstallaxios--save2. Encapsulate axios request-----Download js-cookienpmiJS-cookie-s//Introduce aixosimporttype{AxiosRequestConfig ,AxiosResponse}from"axios";importaxiosfrom'axios';import{ElMess
