一、实现效果
二、实现代码
<view class="code__main flex justify-between">
<!-- 该部分展示给用户- -->
<view
v-for="(n, idx) in code.total"
:key="n"
:class="['code__small-box', { 'code__active': !!code.list[idx] }]"
@click="onClick(idx)"
>
<view :class="[{ 'code__focus-move': code.curIdx == n || (isFocus && code.list.length == idx) }]">
{{ code.curIdx == n ? null : code.list[idx] }}
</view>
</view>
<!-- 输入框隐藏 -->
<input
class="code__hide-input"
v-model="code.inputVal"
type="text"
maxlength="6"
:focus="focusInput"
@focus="onFocus"
@blur="onBlur"
@input="onInput"
>
</view>
<script setup>
import { ref, reactive } from 'vue'
const code = reactive({
total: 6,
curIdx: 0,
inputVal: '',
list: []
})
function onClick(idx) {
focusInput.value = true
}
function onBlur() {
focusInput.value = false
}
/**
* 聚焦考试码
*/
function onFocus() {
isFocus.value = true
code.curIdx = code.inputVal.length + 1
}
/**
* 输入考试码
*/
function onInput(e) {
code.curIdx = e.detail.cursor + 1 // 判断当前光标所处下标
code.list = code.inputVal.split('')
if (code.total === code.list.length) {
// 输入完毕,开始验证
}
}
</script>
<style lang="scss" scoped>
.code {
&__main {
position: relative;
width: 576rpx;
margin: 66rpx auto;
}
&__small-box {
position: relative;
box-sizing: border-box;
margin: 0 12rpx;
width: 80rpx;
height: 112rpx;
line-height: 112rpx;
text-align: center;
color: #000;
font-size: 48rpx;
background-color: #fff;
border: 2rpx solid #fff;
border-radius: 16rpx;
transition: border 0.3s;
}
&__hide-input {
position: absolute;
right: 99999px;
z-index: 1;
width: 1rpx;
height: 1rpx;
min-height: 1rpx;
color: #fff;
caret-color: none;
background-color: none;
outline: none;
}
&__hide-input:focus {
color: #fff;
outline: none;
caret-color: none;
background-color: none;
}
&__focus-move {
position: absolute;
top: 35rpx;
left: 38rpx;
height: 50rpx;
width: 4rpx;
background-color: #3C9CFF;
}
&__active {
border: 2rpx solid #3C9CFF !important;
}
}
</style>
三、过程遇到的坑
- 问题过程:隐藏输入框使用方案width: 0px时, 会出现Andorid机型无法唤起键盘;
- 解决方案:width至少为0.1px + 定位right:-99999px