vue自定义键盘

在这里插入图片描述

<template>
    <div class="mark" @click="() => {
        emit('close')
    }"></div>
    <div class="mycar">
        <div class="mycar_list">
            <div class="mycar_list_con">
                <p class="mycar_list_p">车牌号</p>
                <div class="mycar_list_carnum">
                    <span class="mycar_list_div_span" v-for="(item, index) in carNumList"
                        :class="{ active: item, active_cursor: activeCursor == index, lastCursor: activeCursor == 7, first_style_name: item == '省' }"
                        @click="changeCarNum(index)" :key="index">{{ item }}</span>
                </div>
            </div>
        </div>
        <div class="mycar_list_numlist">
            <span class="mycar_list_numlist_cancel" :class="{ mycar_list_numlist_more: !shwoProvinceFlag }" @click="isOver">取消</span>
            <span class="mycar_list_numlist_confirm" :class="{ mycar_list_numlist_more: !shwoProvinceFlag }" @click="addCar">确定</span>
            <div class="mycar_list_numlist_province" v-if="shwoProvinceFlag">
                <span class="mycar_list_numlist_province_span" v-for="(item, index) in province" :key="index"
                    @click="changeProvince(item)">{{ item }}</span>
                <span class="mycar_list_numlist_province_span province_span_last">
                    <image src="https://file.wonder-link.net/81da6b97794e456db5c135aa3e620cce.png"></image>
                </span>
            </div>
            <div class="mycar_list_numlist_letterList" v-else>
                <div class="mycar_list_numlist_letterList_div">
                    <span class="mycar_list_numlist_letterList_div_span" v-for="(item, index) in numList"
                        :class="{ numlistStyle: activeCursor == 1 }" :key="index" @click="getNum(item)">{{ item }}</span>
                </div>
                <div class="mycar_list_numlist_letterList_div letterList_list">
                    <span class="mycar_list_numlist_letterList_div_span type_class_span" v-for="(item, index) in letterList"
                        :key="index" :class="{ type_class_disabled: (item == 'O' || item == 'I') }"
                        @click="changeLetter(item, index)">{{ item }}</span>
                    <span class="mycar_list_numlist_letterList_div_span province_span_last" style="flex: 0.5;"
                        @click="deleteCarNum">
                        <image src="https://file.wonder-link.net/81da6b97794e456db5c135aa3e620cce.png"></image>
                    </span>
                </div>
                <div class="mycar_list_numlist_letterList_div letterList_typeList">
                    <span class="mycar_list_numlist_letterList_div_span type_class_span" v-for="(item, index) in typeList"
                        :class="{ type_class_disabled: activeCursor != 6 }" :key="index" @click="getTypeCar(item, index)">{{
                            item
                        }}</span>
                </div>
            </div>
        </div>
    </div>
</template>
<script setup lang="ts">
import { reactive, ref, onMounted, watch } from 'vue';

const emit = defineEmits(['complete', 'close']);
const carNumList: any = ref(["省", "", "", "", "", "", "", "新"])
const province = ["京", "沪", "浙", "苏", "粤", "鲁", "晋", "冀",
    "豫", "川", "渝", "辽", "吉", "黑", "皖", "鄂",
    "津", "贵", "云", "桂", "琼", "青", "新", "藏",
    "蒙", "宁", "甘", "陕", "闽", "赣", "湘", "使", "领", "警", "学", "港", "澳"
];
const numList = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"];
const letterList = ['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'Z', 'X', 'C', 'V', 'B', 'N', 'M']
const typeList = ["学", "警", "港", "澳"]
const plateNo = ref('');
const isOverFlag = ref(true)
const disabled = ref(true)
const shwoProvinceFlag = ref(true)
const activeCursor = ref(0); // 光标 index
const props = defineProps({
    currentTitle: {
        type: String,
        default: ''
    }
});

// 监控车牌
watch(carNumList.value, (list) => {
    let flagDisabled = list.every((item) => item.trim().length > 0)
    disabled.value = !flagDisabled || list[0] == '省'
})

// 车牌改变 光标
const changeCarNum = (index) => {
    isOverFlag.value = true
    if (index > 0) {
        shwoProvinceFlag.value = false
    } else {
        shwoProvinceFlag.value = true
    }
    activeCursor.value = index
}
// 省份修改
const changeProvince = (item) => {
    activeCursor.value = 0;
    carNumList.value[0] = item;
    shwoProvinceFlag.value = false
    activeCursor.value = 1;
}

// 车牌数字输入
const getNum = (item) => {
    if (activeCursor.value == 1) {
        return false
    }
    carNumList.value.splice(activeCursor.value, 1, item);
    if (activeCursor.value <= 6) {
        activeCursor.value += 1
    }
}

// 字母输入
const changeLetter = (item, index) => {
    if (item == 'O' || item == 'I') {
        return
    }
    carNumList.value.splice(activeCursor.value, 1, item);
    if (activeCursor.value <= 6) {
        activeCursor.value += 1
    }
}

// 车牌类型
const getTypeCar = (item, index) => {
    if (activeCursor.value != 6) {
        return false;
    }
    carNumList.value.splice(6, 1, item);
}

// 删除
const deleteCarNum = () => {
    if (activeCursor.value > 0) {
        if (carNumList.value[activeCursor.value].trim().length == 0) {
            activeCursor.value -= 1
        } else if (carNumList.value[activeCursor.value] == '新') {
            activeCursor.value = 6
        }
    }
    if (activeCursor.value == 0) {
        carNumList.value.splice(activeCursor.value, 1, "省");
        shwoProvinceFlag.value = true
    } else if (activeCursor.value == 7) {
        carNumList.value.splice(activeCursor.value, 1, "新");
        shwoProvinceFlag.value = false
    } else {
        carNumList.value.splice(activeCursor.value, 1, "");
        shwoProvinceFlag.value = false
    }

}
// 点击取消
const isOver = () => {
    emit('complete')
}
// 按钮确认添加
const addCar = async () => {
    let arr = [] as any;
    arr = arr.concat(carNumList.value)
    plateNo.value = arr[7] == "新" ? arr.splice(0, 7).join('') : arr.join('');
    if (plateNo.value.length < 7) {
        uni.showToast({
            title: '请输入车牌号',
            icon: 'none',
        }) 
    } else {
        emit('complete', plateNo.value);
    }
}
onMounted(() => {
    if (props.currentTitle) {
        activeCursor.value = 0;
        carNumList.value = Array.from(props.currentTitle);
        shwoProvinceFlag.value = true;
    }
})
</script>
<style lang="scss" scoped>
.mark {
    position: fixed;
    width: 100%;
    height: 100vh;
    top: 0;
    left: 0;
    z-index: 10;
    background: rgba(0, 0, 0, 0.7);
}

.mycar {
    position: fixed;
    width: 100%;
    height: 60vh;
    bottom: 0;
    left: 0;
    z-index: 100;
    background: #fff;

    .mycar_list {
        height: 205rpx;

        >.mycar_list_con {
            background-color: #fff;
            padding: 30rpx 24rpx 44rpx;

            >.mycar_list_p {
                font-size: 30rpx;
                font-family: PingFangSC-Regular, PingFang SC;
                font-weight: 400;
                color: #222222;
                line-height: 42rpx;
                margin-bottom: 19rpx;
            }

            >.mycar_list_carnum {
                display: flex;
                align-items: center;
                justify-content: space-between;

                >.mycar_list_div_span {
                    text-align: center;
                    line-height: 70rpx;
                    width: 70rpx;
                    height: 70rpx;
                    border-radius: 6rpx;
                    border: 2rpx solid #A6A6A6;

                    &.active {
                        border: 2rpx solid #333333;
                    }

                    &.active_cursor {
                        border: 2rpx solid #FF6634;

                        &:last-child {
                            border: 2rpx dashed #FF6634;

                            &.lastCursor {
                                color: #000;
                            }
                        }
                    }

                    &:last-child {
                        border: 2rpx dashed #FF6634;
                        color: #ccc;
                    }

                    &.first_style_name {
                        color: #ccc;
                    }
                }
            }
        }
    }

    .mycar_list_numlist {
        >.mycar_list_numlist_cancel {
            position: absolute;
            left: 20rpx;
            bottom: 444rpx;
            color: #333;
            z-index: 10;

            &.mycar_list_numlist_more {
                bottom: 494rpx;
            }
        }

        >.mycar_list_numlist_confirm {
            position: absolute;
            right: 20rpx;
            bottom: 444rpx;
            color: #FF6634;
            z-index: 10;

            &.mycar_list_numlist_more {
                bottom: 494rpx;
            }
        }

        >.mycar_list_numlist_province {
            position: absolute;
            bottom: 0rpx;
            flex-wrap: wrap;
            text-align: center;
            padding-top: 100rpx;
            padding-bottom: 20rpx;
            background: rgba(210, 213, 219, 0.9);

            >.mycar_list_numlist_province_span {
                width: 60rpx;
                height: 80rpx;
                background-color: #fff;
                text-align: center;
                line-height: 80rpx;
                display: inline-block;
                margin: 10rpx 6rpx;
                box-shadow: 0rpx 2rpx 0rpx 0rpx rgba(0, 0, 0, 0.35);
                border-radius: 10rpx;

                &.province_span_last {
                    box-sizing: border-box;
                    width: 90rpx;
                    position: relative;

                    >image {
                        position: relative;
                        top: 5rpx;
                        left: 0rpx;
                        height: 34rpx;
                        width: 46rpx;
                    }
                }
            }
        }

        .mycar_list_numlist_letterList {
            position: absolute;
            bottom: 0rpx;
            padding-top: 100rpx;
            padding-bottom: 20rpx;
            background: rgba(210, 213, 219, 0.9);

            >.mycar_list_numlist_letterList_div {
                text-align: center;

                >.mycar_list_numlist_letterList_div_span {
                    width: 60rpx;
                    height: 70rpx;
                    background-color: #fff;
                    text-align: center;
                    line-height: 70rpx;
                    display: inline-block;
                    margin: 10rpx 6rpx;
                    box-shadow: 0rpx 2rpx 0rpx 0rpx rgba(0, 0, 0, 0.35);
                    border-radius: 10rpx;

                    &.type_class_span {
                        &.type_class_disabled {
                            color: #ccc;
                        }
                    }

                    &.numlistStyle {
                        color: #ccc;
                    }
                }

                &.letterList_list {
                    // padding: 0 36rpx;
                    padding: 0 20rpx;
                    display: flex;
                    justify-content: space-between;
                    flex-wrap: wrap;

                    >.province_span_last {
                        width: 90rpx;
                        position: relative;

                        >image {
                            position: relative;
                            top: 5rpx;
                            left: 0rpx;
                            height: 34rpx;
                            width: 46rpx;
                        }
                    }
                }

                &.letterList_typeList {
                    padding: 0 10px;
                    display: flex;
                    justify-content: space-between;

                    >.mycar_list_numlist_letterList_div_span {
                        width: 160rpx;
                    }
                }
            }
        }
    }
}</style>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值