<template> 
 | 
    <view class="so-mask" v-if="show"> 
 | 
        <view style="height: 100%" @tap="$emit('close')" /> 
 | 
        <view class="so-plate animation-scale-up"> 
 | 
            <view class="so-plate-head"> 
 | 
                <view class="so-plate-type"> 
 | 
                    <radio-group @change="typeChange"> 
 | 
                        <label> 
 | 
                            <radio value="1" :checked="type===1" /> 
 | 
                            普通车牌 
 | 
                        </label> 
 | 
                        <label> 
 | 
                            <radio value="2" :checked="type===2" /> 
 | 
                            新能源车牌 
 | 
                        </label> 
 | 
                    </radio-group> 
 | 
                </view> 
 | 
            </view> 
 | 
            <view class="so-plate-body"> 
 | 
                <view class="so-plate-word" :class="{ active: currentInputIndex == 0 }" @tap="inputSwitch" 
 | 
                    data-index="0"> 
 | 
                    <text>{{ currentInputValue[0] }}</text> 
 | 
                </view> 
 | 
                <view class="so-plate-word" :class="{ active: currentInputIndex == 1 }" @tap="inputSwitch" 
 | 
                    data-index="1"> 
 | 
                    <text>{{ currentInputValue[1] }}</text> 
 | 
                </view> 
 | 
                <view class="so-plate-dot"></view> 
 | 
                <view class="so-plate-word" :class="{ active: currentInputIndex == 2 }" @tap="inputSwitch" 
 | 
                    data-index="2"> 
 | 
                    <text>{{ currentInputValue[2] }}</text> 
 | 
                </view> 
 | 
                <view class="so-plate-word" :class="{ active: currentInputIndex == 3 }" @tap="inputSwitch" 
 | 
                    data-index="3"> 
 | 
                    <text>{{ currentInputValue[3] }}</text> 
 | 
                </view> 
 | 
                <view class="so-plate-word" :class="{ active: currentInputIndex == 4 }" @tap="inputSwitch" 
 | 
                    data-index="4"> 
 | 
                    <text>{{ currentInputValue[4] }}</text> 
 | 
                </view> 
 | 
                <view class="so-plate-word" :class="{ active: currentInputIndex == 5 }" @tap="inputSwitch" 
 | 
                    data-index="5"> 
 | 
                    <text>{{ currentInputValue[5] }}</text> 
 | 
                </view> 
 | 
                <view class="so-plate-word" :class="{ active: currentInputIndex == 6 }" @tap="inputSwitch" 
 | 
                    data-index="6"> 
 | 
                    <text>{{ currentInputValue[6] }}</text> 
 | 
                </view> 
 | 
                <view class="so-plate-word" :class="{ active: currentInputIndex == 7 }" @tap="inputSwitch" 
 | 
                    v-if="type == 2" data-index="7"> 
 | 
                    <text>{{ currentInputValue[7] }}</text> 
 | 
                </view> 
 | 
            </view> 
 | 
            <view class="so-plate-foot"> 
 | 
                <view class="so-plate-keyboard" :style="{height:keyboardHeight}"> 
 | 
                    <view id="keyboard"> 
 | 
                        <block v-if="inputType == 1"> 
 | 
                            <view hover-class="hover" class="so-plate-key" v-for="el of provinceText" :key="el" 
 | 
                                :data-value="el" @tap="chooseKey">{{ el }}</view> 
 | 
                        </block> 
 | 
                        <block v-if="inputType == 1"> 
 | 
                            <text class="so-plate-key fill-block"></text> 
 | 
                        </block> 
 | 
                        <block v-if="inputType >= 3"> 
 | 
                            <view hover-class="hover" class="so-plate-key" v-for="el of numberText" :key="el" 
 | 
                                :data-value="el" @tap="chooseKey">{{ el }}</view> 
 | 
                        </block> 
 | 
                        <block v-if="inputType >= 2"> 
 | 
                            <view hover-class="hover" class="so-plate-key" v-for="el of wordText" :key="el" 
 | 
                                :data-value="el" @tap="chooseKey">{{ el }}</view> 
 | 
                        </block> 
 | 
                        <block v-if="inputType == 3"> 
 | 
                            <text v-for="el of fillBlock" :key="el.num" class="so-plate-key fill-block"></text> 
 | 
                        </block> 
 | 
                        <block v-if="inputType == 4"> 
 | 
                            <view hover-class="hover" class="so-plate-key" v-for="el of lastWordText" :key="el" 
 | 
                                :data-value="el" @tap="chooseKey">{{ el }}</view> 
 | 
                        </block> 
 | 
                        <text v-if="inputType == 4" class="so-plate-key fill-block"></text> 
 | 
                    </view> 
 | 
                </view> 
 | 
                <view class="so-plate-btn-group"> 
 | 
                    <view> 
 | 
                        <button class="so-plate-btn so-plate-btn--cancel" @tap="$emit('close')">取消</button> 
 | 
                    </view> 
 | 
                    <view> 
 | 
                        <button class="so-plate-btn so-plate-btn--delete" @tap="deleteKey">删除</button> 
 | 
                        <button class="so-plate-btn so-plate-btn--submit" @tap="exportPlate">完成</button> 
 | 
  
 | 
                    </view> 
 | 
  
 | 
                </view> 
 | 
            </view> 
 | 
        </view> 
 | 
    </view> 
 | 
    <view v-else></view> 
 | 
</template> 
 | 
<script> 
 | 
    export default { 
 | 
        name: 'uni-plate-input', 
 | 
        data() { 
 | 
            return { 
 | 
                show: false, 
 | 
                type: 1, //车牌类型 
 | 
                currentInputIndex: 0, //当前编辑的输入框 
 | 
                currentInputValue: ['', '', '', '', '', '', ''], 
 | 
                fillBlock: [{ 
 | 
                    num: 11 
 | 
                }, { 
 | 
                    num: 12 
 | 
                }, { 
 | 
                    num: 13 
 | 
                }, { 
 | 
                    num: 14 
 | 
                }, { 
 | 
                    num: 15 
 | 
                }, { 
 | 
                    num: 16 
 | 
                }], //避免:key报错 
 | 
                keyboardHeightInit: false, 
 | 
                keyboardHeight: 'auto', 
 | 
                provinceText: [ 
 | 
                    '粤', 
 | 
                    '京', 
 | 
                    '冀', 
 | 
                    '沪', 
 | 
                    '津', 
 | 
                    '晋', 
 | 
                    '蒙', 
 | 
                    '辽', 
 | 
                    '吉', 
 | 
                    '黑', 
 | 
                    '苏', 
 | 
                    '浙', 
 | 
                    '皖', 
 | 
                    '闽', 
 | 
                    '赣', 
 | 
                    '鲁', 
 | 
                    '豫', 
 | 
                    '鄂', 
 | 
                    '湘', 
 | 
                    '桂', 
 | 
                    '琼', 
 | 
                    '渝', 
 | 
                    '川', 
 | 
                    '贵', 
 | 
                    '云', 
 | 
                    '藏', 
 | 
                    '陕', 
 | 
                    '甘', 
 | 
                    '青', 
 | 
                    '宁', 
 | 
                    '新' 
 | 
                ], 
 | 
                numberText: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'], 
 | 
                wordText: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 
 | 
                    'V', 'W', 'X', 'Y', 'Z' 
 | 
                ], 
 | 
                lastWordText: ['挂', '港', '学', '领', '警'] 
 | 
            }; 
 | 
        }, 
 | 
        props: { 
 | 
            plate: { 
 | 
                type: String 
 | 
            } 
 | 
        }, 
 | 
        computed: { 
 | 
            //输入框类型 
 | 
            inputType() { 
 | 
                switch (this.currentInputIndex) { 
 | 
                    case 0: 
 | 
                        return 1; 
 | 
                        break; 
 | 
                    case 1: 
 | 
                        return 2; 
 | 
                        break; 
 | 
                    case 2: 
 | 
                        return 3; 
 | 
                        break; 
 | 
                    case 3: 
 | 
                        return 3; 
 | 
                        break; 
 | 
                    case 4: 
 | 
                        return 3; 
 | 
                        break; 
 | 
                    case 5: 
 | 
                        return 3; 
 | 
                        break; 
 | 
                    case 6: 
 | 
                        return this.type == 2 ? 3 : 4; 
 | 
                        break; 
 | 
                    case 7: 
 | 
                        return 4; 
 | 
                        break; 
 | 
                    default: 
 | 
                        return 1; 
 | 
                        break; 
 | 
                } 
 | 
            } 
 | 
        }, 
 | 
        watch: { 
 | 
            currentInputIndex: function(n, o) { 
 | 
                if (!this.keyboardHeightInit) return 
 | 
                this.$nextTick(() => { 
 | 
                    this.changeKeyboardHeight() 
 | 
                }) 
 | 
            } 
 | 
        }, 
 | 
        methods: { 
 | 
            open() { 
 | 
                this.type = 1 
 | 
                this.currentInputIndex = 0 
 | 
                this.currentInputValue = ['', '', '', '', '', '', ''] 
 | 
                this.show = true 
 | 
                setTimeout(() => { //在动画结束之后才开始获取 
 | 
                    this.$nextTick(() => { 
 | 
                        this.changeKeyboardHeight() 
 | 
                    }) 
 | 
                }, 500); 
 | 
            }, 
 | 
            close() { 
 | 
                this.show = false 
 | 
            }, 
 | 
            //车牌类型切换 
 | 
            typeChange(e) { 
 | 
                this.$emit("typeChange", e.detail.value); 
 | 
                const { 
 | 
                    value 
 | 
                } = e.detail; 
 | 
                this.type = parseInt(value) 
 | 
                this.currentInputIndex = 0 
 | 
                if (value == 1) { 
 | 
                    this.currentInputValue = ['', '', '', '', '', '', ''] 
 | 
                } else { 
 | 
                    this.currentInputValue = ['', '', '', '', '', '', '', ''] 
 | 
                } 
 | 
            }, 
 | 
            inputSwitch(e) { 
 | 
                const { 
 | 
                    index 
 | 
                } = e.currentTarget.dataset; 
 | 
                this.currentInputIndex = parseInt(index); 
 | 
            }, 
 | 
            chooseKey(e) { 
 | 
                const { 
 | 
                    value 
 | 
                } = e.currentTarget.dataset; 
 | 
                this.$set(this.currentInputValue, this.currentInputIndex, value); 
 | 
                if (this.type == 1 && this.currentInputIndex < 6) { 
 | 
                    this.currentInputIndex++ 
 | 
                } 
 | 
                if (this.type == 2 && this.currentInputIndex < 7) { 
 | 
                    this.currentInputIndex++ 
 | 
                } 
 | 
            }, 
 | 
            deleteKey() { 
 | 
                this.$set(this.currentInputValue, this.currentInputIndex, '') 
 | 
                if (this.currentInputIndex != 0) this.currentInputIndex-- 
 | 
            }, 
 | 
            exportPlate() { 
 | 
                const plate = this.currentInputValue.join('') 
 | 
                let err = false 
 | 
                if (this.type === 1 && plate.length != 7) { 
 | 
                    err = true 
 | 
                } else if (this.type === 2 && plate.length != 8) { 
 | 
                    err = true 
 | 
                } 
 | 
                if (err) return uni.showToast({ 
 | 
                    title: '请输入完整的车牌号码', 
 | 
                    icon: 'none' 
 | 
                }) 
 | 
  
 | 
                this.$emit('export', plate) 
 | 
            }, 
 | 
            changeKeyboardHeight() { 
 | 
                const that = this 
 | 
                const query = uni.createSelectorQuery().in(this); 
 | 
                query.select('#keyboard').boundingClientRect(); 
 | 
                query.exec(function(res) { 
 | 
                    if (res && res[0]) { 
 | 
                        that.keyboardHeight = res[0].height + uni.upx2px(30) + 'px' 
 | 
                        that.keyboardHeightInit = true 
 | 
                    } 
 | 
                }); 
 | 
            } 
 | 
        }, 
 | 
        mounted() { 
 | 
            // console.log(this.plate); 
 | 
    //         const plateKey = this.plate.split('') 
 | 
    //         if (plateKey.length === 7) { 
 | 
    //             this.type = 1 
 | 
    //         } else if (plateKey.length === 8) { 
 | 
    //             this.type = 2 
 | 
    //         } 
 | 
    //         if (plateKey.length === 7 || plateKey.length === 8) { 
 | 
    //             this.currentInputValue = plateKey 
 | 
    //             this.currentInputIndex = plateKey.length - 1 
 | 
    //         } 
 | 
  
 | 
    //         setTimeout(() => { //在动画结束之后才开始获取 
 | 
    //             this.$nextTick(() => { 
 | 
    //                 this.changeKeyboardHeight() 
 | 
    //             }) 
 | 
    //         }, 500); 
 | 
        } 
 | 
    }; 
 | 
</script> 
 | 
<style scoped lang="less"> 
 | 
    .so-mask { 
 | 
        position: fixed; 
 | 
        top: 0; 
 | 
        bottom: 0; 
 | 
        right: 0; 
 | 
        left: 0; 
 | 
        background: rgba(0, 0, 0, 0.5); 
 | 
        z-index: 99999; 
 | 
    } 
 | 
    .so-plate { 
 | 
        box-sizing: border-box; 
 | 
        position: absolute; 
 | 
        bottom: 0; 
 | 
        width: 100%; 
 | 
        left: 0; 
 | 
        background: #fff; 
 | 
        padding: 25upx 25upx 0 25upx; 
 | 
        &-head { 
 | 
            display: flex; 
 | 
            justify-content: space-between; 
 | 
            align-items: center; 
 | 
        } 
 | 
        &-type {             
 | 
            flex:1; 
 | 
            display:block; 
 | 
            label { 
 | 
                display: inline-block; 
 | 
                min-height: 32upx; 
 | 
                font-size: 26upx; 
 | 
                margin-right: 10upx; 
 | 
            } 
 | 
        } 
 | 
        &-body { 
 | 
            box-sizing: border-box; 
 | 
            padding: 30upx 0; 
 | 
            display: flex; 
 | 
            justify-content: space-between; 
 | 
            align-items: center; 
 | 
        } 
 | 
        &-word { 
 | 
            border: 1upx solid #ccc; 
 | 
            border-radius: 10upx; 
 | 
            height: 0; 
 | 
            margin: 0 5upx; 
 | 
            box-sizing: border-box; 
 | 
            padding-bottom: calc((100% - 70upx) / 7); 
 | 
            width: calc((100% - 70upx) / 7); 
 | 
            position: relative; 
 | 
            &.active { 
 | 
                border-color: #007aff; 
 | 
                box-shadow: 0 0 15upx 0 #007aff; 
 | 
            } 
 | 
            text { 
 | 
                position: absolute; 
 | 
                top: 50%; 
 | 
                left: 50%; 
 | 
                transform: translateX(-50%) translateY(-50%); 
 | 
                font-weight: 700; 
 | 
                font-size: 32upx; 
 | 
            } 
 | 
        } 
 | 
        &-dot { 
 | 
            width: 15upx; 
 | 
            height: 15upx; 
 | 
            background: #ccc; 
 | 
            border-radius: 50%; 
 | 
            margin: 0 5upx; 
 | 
        } 
 | 
        &-keyboard { 
 | 
            background: #eee; 
 | 
            margin-left: -25upx; 
 | 
            margin-right: -25upx; 
 | 
            padding: 20upx 25upx 10upx 25upx; 
 | 
            box-sizing: border-box; 
 | 
            transition: all .3s; 
 | 
            &>view{ 
 | 
                display: flex; 
 | 
                flex-wrap: wrap; 
 | 
                justify-content: space-between; 
 | 
            } 
 | 
        } 
 | 
        &-key { 
 | 
            display: block; 
 | 
            background: #fff; 
 | 
            border-radius: 10upx; 
 | 
            box-shadow: 0 0 8upx 0 #bbb; 
 | 
            width: 80upx; 
 | 
            height: 80upx; 
 | 
            margin: 5upx 0; 
 | 
            font-size: 32upx; 
 | 
            text-align: center; 
 | 
            display: flex; 
 | 
            align-items: center; 
 | 
            justify-content: center; 
 | 
            position: relative; 
 | 
            &.hover { 
 | 
                background: #efefef; 
 | 
            } 
 | 
            &.fill-block { 
 | 
                width: 80upx; 
 | 
                height: 80upx; 
 | 
                background: none; 
 | 
                box-shadow: none; 
 | 
            } 
 | 
        } 
 | 
        &-btn { 
 | 
            display: inline-block; 
 | 
            background: #fff; 
 | 
            border-radius: 10upx; 
 | 
            box-shadow: 0 0 10upx 0 #bbb; 
 | 
            font-size: 28upx; 
 | 
            text-align: center; 
 | 
            margin:0 0 0 10upx; 
 | 
            padding:0 25upx; 
 | 
            &-group{ 
 | 
                display: flex; 
 | 
                justify-content: space-between; 
 | 
                background: #eee; 
 | 
                margin-left: -25upx; 
 | 
                margin-right: -25upx; 
 | 
                box-sizing: border-box; 
 | 
                padding: 0 25upx 10upx 25upx; 
 | 
            } 
 | 
            &--cancel{ 
 | 
                margin:0; 
 | 
            } 
 | 
            &--submit{ 
 | 
                background:#5773f9; 
 | 
                color:#fff; 
 | 
            } 
 | 
            &--delete{ 
 | 
                color:#fd6b6d; 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
      
 | 
      
 | 
    .animation-scale-up { 
 | 
        animation-duration: .2s; 
 | 
        animation-timing-function: ease-out; 
 | 
        animation-fill-mode: both; 
 | 
        animation-name: scale-up 
 | 
    } 
 | 
    @keyframes scale-up { 
 | 
        0% { 
 | 
            opacity: .8; 
 | 
            transform: scale(.8) 
 | 
        } 
 | 
      
 | 
        100% { 
 | 
            opacity: 1; 
 | 
            transform: scale(1) 
 | 
        } 
 | 
    } 
 | 
</style> 
 |