uniapp输入车牌号组件

plate:

<template>
	<view>
		<view class="plate" :class="{show:show}">
			<view :class="['item',{active:index===0}]" @click.stop="handleChange(0)">{{plate[0]}}</view>
			<view :class="['item ml10',{active:index===1}]" @click="handleChange(1)">{{plate[1]}}</view>
			<view>●</view>
			<view :class="['item',{active:index===2}]" @click="handleChange(2)">{{plate[2]}}</view>
			<view :class="['item ml10',{active:index===3}]" @click="handleChange(3)">{{plate[3]}}</view>
			<view :class="['item ml10',{active:index===4}]" @click="handleChange(4)">{{plate[4]}}</view>
			<view :class="['item ml10',{active:index===5}]" @click="handleChange(5)">{{plate[5]}}</view>
			<view :class="['item ml10',{active:index===6}]" @click="handleChange(6)">{{plate[6]}}</view>
			<view :class="['item ml10 column',{active:index===7}]" @click="handleChange(7)">
				<template v-if="newEnergy">
					<text>{{plate[7]}}</text>
				</template>
				<template v-else>
					<u-icon name="plus-circle"></u-icon>
					<view style="font-size: 20upx;">新能源</view>
				</template>
			</view>
		</view>
		<section class="panel" :class="{show:show}">
			<view class="header">
				<view class="p24" style="color: #267EF1;" @click="panelReset">重置</view>
				<view src="/static/down.png" style="width: 140upx;" mode="widthFix" @click="panelHide" />
				<view class="p24" @click="panelHide">关闭</view>
			</view>
			<view class="panelList clearfix">
<!--				<view class="item" v-for="(item,index) of currentDatas" @click.stop="clickKeyBoard(item)">{{item}}</view>-->
        <!-- 其他组件内容 -->
        <view v-for="(item, index) in currentDatas" :key="index">
          <button
              class="item"
              :disabled="isDisabled(index)"
              @click="!isDisabled(index) && clickKeyBoard(item)"
          >
            {{ item }}
          </button>
        </view>
			</view>
			<view class="backspace shadow" @click="backspace">
				<u-icon name="backspace" color="#333" size="34"></u-icon>
			</view>
		</section>
	</view>
</template>

<script>
	export default {
		name: "index",
		props: {
			characterDatas: {
				type: Array,
				default () {
					return [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q',
						'R',
						'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '港', '澳', '学', '领'
					]
				}
			},
			areaDatas: {
				type: Array,
				default () {
					return ['京', '沪', '粤', '津', '冀', '晋', '蒙', '黑', '吉', '辽', '苏', '浙', '皖', '闽', '赣', '鲁', '豫', '鄂', '湘', '桂',
						'琼', '渝', '川', '贵', '云', '藏',
						'陕', '甘', '青', '宁', '新', '临', '领', '警', '学', '港', '澳'
					]
				}
			},
			defaultPlate:{
				type:Array,
				default () {
					return Array.from({
					length: 8
				}, v => '')
				}
			}
		},
		data() {
			return {
				show: false,
				index: -1,
				newEnergy: false,
				plate: this.defaultPlate
			}
		},
		created() {

		},
		computed: {
			currentDatas() {
				return this.index === 0 ? this.areaDatas : this.characterDatas;
			}
		},
		watch: {
      defaultPlate(newValue) {
        this.plate = newValue;
      },
			plate(value) {
				this.$emit("listenPlateChange",value);
			}
		},
    methods: {
			panelShow() {
				this.show = true;
			},
			panelHide() {
				this.show = false;
			},
			handleChange(index) {
				this.index = index;
				if (index === 7) {
					this.newEnergy = true;
				}
				this.panelShow();
			},
			clickKeyBoard(item) {
				if (this.index < 7 || this.newEnergy) {
					this.$set(this.plate, this.index, item);
				}

				if (this.index < 7) {
					this.index++;
				}
			},
			backspace() {
				if (this.index > 0) {
					this.$set(this.plate, this.index, '');
					this.index--;
				}
			},
			panelReset() {
				this.index = 0;
				this.plate = Array.from({
					length: 8
				}, v => '');
				this.newEnergy = false;
			},
      isDisabled(index) {
        if (this.index === 0) {
          return index >= (this.areaDatas.length - 6);
        }
        else {
          const lastFour = this.characterDatas.length - 4;
          if (this.index === 1) {
            return typeof this.characterDatas[index] === 'number' || index >= lastFour;
          }
          return index >= lastFour;
        }
        return false;
      }
		}
	}
</script>

<style scoped lang='scss'>
	.plate {
		display: flex;
		align-items: center;
		justify-content: center;

		.item {
      width: calc(100% / 7 - 4rpx);
			height: 90rpx;
			background-color: #F2F3F5;
			border: 1px solid #F2F3F5;
			border-radius: 10rpx;
			display: flex;
			align-items: center;
			justify-content: center;
      font-size: 24px;
			&.ml10 {
				margin-left: 10upx;
			}

			&.column {
				flex-direction: column;
        border: 1px dashed #4CB58E;
			}

			&.active {
				background-color: #EDF7FF;
        border: 1px solid #5294DB;
			}
		}
	}

	.panel {
		position: fixed;
		left: 0;
		width: 100%;
		bottom: 0;
		z-index: 999;
		box-sizing: border-box;
		background-color: #EFEFEF;
		transition: all 0.3s ease;
		transform: translateY(100%);

		.p24 {
			padding: 24upx;
		}

		&.show {
			transform: translateX(0);
		}

		.header {
			display: flex;
			align-items: center;
			justify-content: space-between;
			height: 80upx;
			border-top: 1px solid #c9cacd;
			//border-bottom: 1px solid #c9cacd;
		}

		.panelList {
			padding: 20upx;
			text-align: center;

			.item {
        float: left;
        width: calc(100% / 10 - 10rpx);
        height: 76rpx;
        background: #fff;
        border-radius: 10rpx;
        display: flex;
        justify-content: center;
        align-items: center;
        margin: 0 10rpx 10rpx 0;
        font-size: 32rpx;
        font-weight: 600;
        box-shadow: 0 0 4px 1px #e5e5e5;
      }
		}

		.backspace {
			position: absolute;
			bottom: 25rpx;
			right: 26rpx;
			width: 100rpx;
			height: 84rpx;
			background-color: #cbcbcb;
			border-radius: 10rpx;
			display: flex;
			align-items: center;
			justify-content: center;
		}
	}

	.clearfix::before,
	.clearfix::after {
		content: ' ';
		display: table;
		height: 0;
		line-height: 0;
		visibility: hidden;
		clear: both;
	}
</style>
<template>
  <view class="carPage" >
    <view class="top" >
      <image  src="http://192.168.3.200:9090/iot//workLog/2024/09/11/ed115f5c9b7f4323a2f4f47d8e87190f.png"  style="width: 100%; height: 340rpx; " />
    </view>
    <view class="card">
      <view style="font-size: 18px;font-weight: 600;">车牌号码</view>
      <view style="margin: 50rpx 0; ">
        <plate @listenPlateChange="plateChange" :defaultPlate="plateNumber" />
      </view>
      <view style="margin-bottom: 20rpx;">
        <u-button   type="primary" text="下一步" @click="checkPark"></u-button>
      </view>
    </view>
  </view>
</template>

<script>
import plate  from '@/components/plate/index.vue'
import {checkPlate} from "../api";
import {mapGetters, mapMutations} from "vuex";
export default {
  name: "carNumber",
  components: { 
    plate
  },
  data() {
    return {
      plateNumber:[],
      isCart: false, // 是否为月卡服务
    }
  },
  props: {
    isShow: {
      type: Boolean,
      default: false
    }
  },
  onLoad(query) {
    this.isCart = query.menu === 'wx-parking' ? true : false
  },
  computed: {
    ...mapGetters(['carInfo', 'freeCarInfo'])
  },
  methods: {
    ...mapMutations(['setCarInfo','setFreeCar']),
    plateChange(val){
      this.plateNumber = val  // 获取车牌号
    },
    // 查询车牌号
    checkPark() {
      if(this.plateNumber.length <= 0) {
        uni.$u.toast('请输入车牌号!')
        return
      }
      const params = {
        carLicense: this.plateNumber.join('')
      }
      // 判断是否为月卡服务,跳转相应页面
      const path = this.isCart ? 'parkingFee' : 'payment'
      checkPlate({params}).then(res => {
        if (this.isCart) {
          // 月卡,存储车辆信息,非系统用户存车牌号
          if (res.rows.length === 0) {
            this.setCarInfo({carLicense: this.plateNumber.join('')})
          } else {
            this.setCarInfo(res.rows[0])
          }
        } else {
          // 缴费,存储车辆信息,非系统用户存车牌号
          if (res.rows.length === 0) {
            this.setFreeCar({carLicense: this.plateNumber.join('')})
          } else {
            this.setFreeCar(res.rows[0])
          }
        }
        uni.navigateTo({
          url: `/pages/home/functions/${path}/index`
        })
      })
    },
  },
  onShow() {
    // 非首次输入车牌号时,车牌号从缓存取并回显到输入框中
    const carNo = this.carInfo.carLicense && this.isCart ? this.carInfo.carLicense.split('') : (this.freeCarInfo.carLicense && !this.isCart? this.freeCarInfo.carLicense.split('') : [])
    this.plateNumber = [...carNo, ...Array(8 - carNo.length).fill('')];
  }
}
</script>

<style lang="scss" scoped>
.carPage {
  background: linear-gradient(to bottom, #cceaff,  #f5f5f5);
  padding-bottom: 20rpx;
  width: 100vw;
  position: relative;
  .top {
    width: 100vw;
  }
  .card {
    background-color: #fff;
    margin: 0  16rpx;
    padding: 16rpx;
    border-radius: 16rpx;
  }
}
</style>

store:

import Vue from 'vue'
import Vuex from "vuex"

Vue.use(Vuex)
const store = new Vuex.Store({
    state: {
        carInfo: {},  // 车辆信息
        freeCarInfo: {},  // 缴费车辆信息
    },
    mutations: {
        // 车辆信息
        setCarInfo(state, data) {
            state.carInfo = data
            uni.setStorageSync('carInfo', data);
        },
        // 缴费车辆信息
        setFreeCar(state, data) {
            state.freeCarInfo = data
            uni.setStorageSync('freeCarInfo', data);
        }
    },
    getters: {
        // 获取停车信息
        carInfo(state) {
            if (state.carInfo.carLicense) {
                return state.carInfo
            } else {
                return uni.getStorageSync('carInfo')
            }
        },
        // 获取停车缴费信息
        freeCarInfo(state) {
            if (state.freeCarInfo.carLicense) {
                return state.freeCarInfo
            } else {
                return uni.getStorageSync('freeCarInfo')
            }
        }
    }

})

export default store

实现效果:

uniapp车牌号输入键盘组件是一个用于在uniapp小程序中输入车牌号的自定义键盘组件。该组件基于微信小程序开发的键盘组件思想进行了优化,并增加了挂车车牌号输入和新能源车辆车牌号输入的功能。 你可以使用以下代码来在uniapp小程序中使用车牌号输入键盘组件: ```html <!-- 在模板中引入车牌号输入键盘组件 --> <template> <view> <TrailerKeyboard :show.sync="trailerKeyboardShow" :vehicleNo="trailerForm.trailerNo" @confirm="keyboardconfirm" vehicleType="car"></TrailerKeyboard> </view> </template> <!-- 在script中引入车牌号输入键盘组件 --> <script> import TrailerKeyboard from '@/components/TrailerKeyboard' export default { components: { TrailerKeyboard }, data() { return { trailerKeyboardShow: false, // 控制键盘显示/隐藏的变量 trailerForm: { trailerNo: '' // 车牌号输入框的值 } } }, methods: { keyboardconfirm(value) { // 处理键盘确认事件,value为键盘输入的值 this.trailerForm.trailerNo = value this.trailerKeyboardShow = false // 隐藏键盘 } } } </script> ``` 在上述代码中,`TrailerKeyboard`是车牌号输入键盘组件的名称,`:show.sync`用于控制键盘的显示和隐藏,`:vehicleNo`绑定车牌号输入框的值,`@confirm`监听键盘的确认事件,`vehicleType`用于指定车牌号组件类型,默认为普通车牌号。 你可以根据需要修改代码中的变量和事件处理函数来适应你的实际需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值