uni-車牌輸入功能,類似與支付寶密碼框


 遇到這么一個需求:

 車牌號輸入,並且是每次輸入后,每一位輸入字符在占一個格子。

由於車牌號的構成對於密碼而言比較復雜,否則可以模擬一個鍵盤,來控制和判斷輸入的內容,這樣這個效果就比較簡單。但是用於車牌輸入的鍵盤內容比較多,所以這邊用另外的方法。

首先創建一個input

<input :focus="bFocus" type="text" v-model="sCar" class="ipt-hide" @input="fInput" :maxlength="bIsUnit?7:8" @blur="fBlur" />

添加一些基礎的事件,並且將其隱藏,隱藏樣式比較特殊,可在文末全部代碼處查看

然后創建方框等元素

<view class="car-item" v-for="nIndex in cCarNum" :class="{active:nIndex===sCar.length}" :key="nIndex">
            {{sCar.split('')[nIndex]?sCar.split('')[nIndex].toUpperCase():''}}
        </view>

當點擊方框時,輸入框聚焦,然后輸入的字符處理后挨個排放入框內。

但是這個完成后有個bug,

當輸入字符后,經過多次修改,尤其是在請求之后,隱藏的輸入框被聚焦時,光標會跳到最前,導致內容無法修改,或者輸入的字符永遠在已存在字符的前面。這種情況通過清空字符時解決不了的。

所以解決方案是在請求后重載組件,重載方法是在input上添加key,請求后改變key來實現組件重載

<comp-car @fCb="fCarIpt" ref="compcar" :key="nComp"></comp-car>

nComp: Math.random()

但是重載的方法在小程序上經過測試失效了,更改key並不能讓組件重載,但是小程序內測試時也未出現該bug,所以小程序內就直接清空字符處理后不再進行更多操作;

組件的全部代碼如下:

app:

<template>
    <view class="car" @tap="fFocus">
        <input :focus="bFocus" type="text" v-model="sCar" class="ipt-hide" @input="fInput" :maxlength="bIsUnit?7:8" @blur="fBlur" />
        <view class="car-item" v-for="nIndex in cCarNum" :class="{active:nIndex===sCar.length}" :key="nIndex">
            {{sCar.split('')[nIndex]?sCar.split('')[nIndex].toUpperCase():''}}
        </view>
        <view class="car-item car-change" @tap.stop="fChange"><i class="iconfont">&#xe627</i><text>{{bIsUnit?'新能源':'普通'}}</text></view>
    </view>

</template>

<script>
    export default {
        data() {
            return {
                sCar: '蘇',
                bIsUnit: true,
                bFocus: false,
                cursor: 1
            }
        },
        computed: {
            cCarNum() {
                return this.bIsUnit ? [0, 1, 2, 3, 4, 5, 6] : [0, 1, 2, 3, 4, 5, 6, 7]; //車牌位數
            }
        },
        onLoad(option) {

        },
        methods: {
            fClear() {
                this.sCar = '蘇';
                this.bIsUnit = true;
                this.bFocus = false;
            },
            fChange() {
                this.sCar = '蘇';
                this.bFocus = false;
                this.bIsUnit = !this.bIsUnit;
                this.$emit('fCb', {
                    sCar: this.sCar.toUpperCase(),
                    bIsUnit: this.bIsUnit
                })
            },
            fBlur() {
                this.bFocus = false;
            },
            fFocus() {
                this.bFocus = true;
            },
            fInput() {
                this.$emit('fCb', {
                    sCar: this.sCar.toUpperCase(),
                    bIsUnit: this.bIsUnit
                })
            }
        },
        mounted() {
            this.fClear()
        }
    }
</script>

<style scoped lang="less">
    .car {
        display: flex;
        flex-direction: row;
        justify-content: center;
        align-items: center;
        height: 44px;
        width: 100%;
        padding: 5px;
        box-sizing: border-box;
    }

    .car-item {
        height: 42px;
        width: 36px;
        margin: 0 2px;
        text-align: center;
        line-height: 42px;
        color: #3e3e3e;
        font-size: 18px;
        border: 1px solid #b2b2b2;
        border-radius: 3px;
    }

    .active {
        border-color: #19bbff;
    }

    .ipt-hide {
        position: absolute;
        z-index: -1;
        left: -100%;
        opacity: 0
    }

    .car-change {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        border-style: dotted;
        font-size: 10px;
        line-height: 2;
        color: #7f7f7f;

        .iconfont {
            font-size: 10px;
        }
    }
</style>

小程序內代碼稍有改動,遍歷渲染字符串時可以直接使用數字而不用數組

小程序代碼:

<template>
    <view class="car" @tap="fFocus">
        <input :focus="bFocus" type="text" v-model="sCar" class="ipt-hide" @input="fInput" :maxlength="cCarNum" @blur="fBlur" />
        <view class="car-item" v-for="nIndex in cCarNum" :class="{active:nIndex===sCar.length-1}":key="nIndex">
            {{sCar.split('')[nIndex]?sCar.split('')[nIndex].toUpperCase():''}}
        </view>
        <view class="car-item car-change" @tap.stop="fChange"><i class="iconfont">&#xe627</i><text>{{bIsUnit?'新能源':'普通'}}</text></view>
    </view>
</template>

<script>
    export default {
        data() {
            return {
                sCar: '蘇',
                bIsUnit: true,
                bFocus: false
            }
        },
        computed: {
            cCarNum() {
                return this.bIsUnit ? 7 : 8; //車牌位數
            }
        },
        onLoad(option) {

        },
        methods: {
            fClear() {
                this.sCar = '蘇';
                this.bIsUnit = true;
                this.bFocus = false;
            },
            fChange() {
                this.sCar = '蘇';
                this.bFocus = false;
                this.bIsUnit = !this.bIsUnit;
            },
            fBlur() {
                this.bFocus = false;
            },
            fFocus() {
                this.bFocus = true;
            },
            fInput() {
                this.$emit('fCb', {
                    sCar: this.sCar.toUpperCase(),
                    bIsUnit: this.bIsUnit
                })
            }
        },
        mounted() {
            this.fClear()
        }
    }
</script>

<style scoped lang="less">
    .car {
        display: flex;
        flex-direction: row;
        justify-content: center;
        align-items: center;
        height: 42px;
        width: 100%;
        padding: 5px;
        box-sizing: border-box;
    }

    .car-item {
        height: 42px;
        width: 36px;
        margin: 0 2px;
        text-align: center;
        line-height: 42px;
        color: #3e3e3e;
        font-size: 18px;
        border: 1px solid #b2b2b2;
        border-radius: 3px;
    }

    .active {
        border-color: #19bbff;
    }

    .ipt-hide {
        position: absolute;
        z-index: -1;
        left: -100%;
        opacity: 0
    }

    .car-change {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        border-style: dotted;
        font-size: 10px;
        line-height: 2;
        color: #7f7f7f;

        .iconfont {
            font-size: 10px;
        }
    }
</style>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM