最近写业务的时候一直在和Input打交道,下面几种常见的业务代码分享给大家,以下代码均使用vue框架语法。
验证码四个Input的焦点获取、连删实现,复制
使用场景:验证码的校验,在输入一个验证码之后,焦点移动到自动向像一个输入框
焦点获取
- 实现思路: 获取下一个dom节点,然后focus
<Input
v-for="(code, ind) in codeNameMap"
:id="`input${code}`" // 用户获取input节点
:key="code"
v-model="exchangeCode[code]"
class="code-input"
:max-length="1"
@input="(e) => ind < 4 && handleInput(e, `input${codeNameMap[ind + 1]}`)" // 输入的时候获取下一个位置焦点
/>
const exchangeCode: any = reactive({
one: '',
two: '',
thr: '',
four: '',
})
const domFocus = (code: string) => {
nextTick(() => {
const dom = document.getElementById(code)
const inputDom = dom?.getElementsByTagName('input')
if (inputDom) inputDom[0].focus() // 获取焦点、 // 使用的组件所以input内容较深,大家可根据自己使用情况去获取
})
}
function handleInput(event: any, nextInput: string) {
if (event.target.value.length === event.target.maxLength && nextInput !== null) {
domFocus(nextInput)
}
}
复制功能
- 实现思路: 获取当前输入框的复制内容,再主动赋值,这里赋值的时候提高用户体验,也将焦点获取定位
// input 节点内加入该方法,参照上面Input、这里ind表示需要从哪一个input框开始复制
@paste="(e:any) => handlePaste(e, ind)"
const handlePaste = (e: any, ind: number) => {
const codeNameMap = Object.keys(exchangeCode)
const copyText = e.clipboardData.getData('text') // 获取复制内容
const needCodeLen = codeNameMap.length
const copyTextLen = copyText.length
const copyLen = copyTextLen < needCodeLen ? copyTextLen + ind : needCodeLen // 通过复制内容长度和需要的code长度 获取 真正需要复制的内容及位置
for (let i = ind; i < copyLen; i++) {
exchangeCode[codeNameMap[i]] = copyText[i - ind]
}
// 焦点移动
if (needCodeLen - ind > copyTextLen) {
const focusDom = `input${codeNameMap[ind + copyTextLen]}`
domFocus(focusDom)
e.preventDefault() // 禁止input操作,否则焦点会变成双跳
}
}
连删
实现思路: 监听键盘时间,在键盘为删除的时候清空input数据,并且焦点回到上一个Input
// input 节点内加入该方法,参照上面Input、这里ind表示需要从哪一个input框开始删除
@keyup="(e:any)=>handleKeyUp(e,ind)"
// 在Input内加入方法 @keyup="(e:any)=>handleKeyUp(e,ind)"
const handleKeyUp = (event: any, ind: number) => {
if (event.key === 'Backspace' || event.key === 'Delete') {
if (ind > 0) {
const focusDom = `input${codeNameMap[ind - 1]}`
domFocus(focusDom)
}
}
}
输入框特殊字符实时校验, 及长度限制
- 使用场景:实时校验昵称之类的输入限制,
- 注意:实时校验会遇到一个问题,无法连续输入长中文
- 实现思路: 使用input的API,
compositionStart
compositionEnd
在输入长中文的时候,不对input做实时校验,长中文输入完成再进行校验
<Input
v-model="nick_name"
placeholder="请输入昵称"
clearable
@input="handleInputNickName"
@compositionstart="compositionStart"
@compositionend="compositionEnd"
/>
const DEFAULT_LEN = 11
const isInputChinese = ref(false) // 是否在输入长中文
const handleInputNickName = e => {
if (isInputChinese.value) {
return
}
const value = e.target.value
const pattern = /[^\u4e00-\u9fa5a-zA-Z\d]/g // 只保留中英文数字
const patternTest = /^[a-zA-Z0-9\u4e00-\u9fa5]+$/
const isValid = patternTest.test(value)
if (!isValid && value.trim()) {
toast.warning('不支持特殊字符')
}
const newValue = value.replace(pattern, '')
if (e.target.value.length > DEFAULT_LEN) {
toast.warning('最多支持11个字符')
}
e.target.value = newValue.slice(0, 11) // 字数截断
}
const compositionStart = () => {
isInputChinese.value = true
}
const compositionEnd = e => {
// 长中文输入结束,需要对字符数量进行判断并且截断
isInputChinese.value = false
const newValue = e.target.value
if (newValue.length > DEFAULT_LEN) {
toast.warning('最多支持11个字符')
e.target.value = newValue.slice(0, 11)
}
}