carKeyboard.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  1. <template>
  2. <!--车牌号输入组件-->
  3. <view v-if="show" class="trailer-keyboard">
  4. <u-popup :show="show">
  5. <view class="trailer-keyboard">
  6. <view class="keyBoard_content">
  7. <!-- header -->
  8. <view class="top-part flex">
  9. <view class="font-30 close" @click="closeKeyboard">
  10. <u-icon name="close"></u-icon>
  11. </view>
  12. <view class="message color-333">输入车牌号</view>
  13. <view
  14. class="font-30 confirm"
  15. :class="{'confirm-active': confirmBtnFocus}"
  16. @click="confirmKeyboard">确定
  17. </view>
  18. </view>
  19. <!-- input checkbox -->
  20. <view class="input-and-checkbox">
  21. <!-- input -->
  22. <view class="license flex">
  23. <view
  24. v-for="(item,index) in codeList"
  25. :key="index"
  26. class="edit-text"
  27. :class="{'border-active': currentFocus === index,'space-left': index === 2}">
  28. <view>{{item.value}}</view>
  29. </view>
  30. </view>
  31. <!-- checkbox -->
  32. <view v-if="vehicleType === 'car' && checkboxShow" class="checkbox-box">
  33. <!-- -->
  34. <u-checkbox-group
  35. class="uCheckbox"
  36. v-model="checkboxList"
  37. @change="checkboxChange"
  38. >
  39. <u-checkbox
  40. :label="'新能源车'"
  41. :name="'新能源车'"
  42. shape="circle"
  43. activeColor="#27B57D"
  44. :checked="isNewEnergy"
  45. >
  46. </u-checkbox>
  47. </u-checkbox-group>
  48. </view>
  49. </view>
  50. <!-- 键盘 -->
  51. <view class="keyboard-content">
  52. <!-- 省份键盘 -->
  53. <template v-if="provinceBoardShow">
  54. <view class="province-keyboard flex">
  55. <view
  56. class="td td-nor color-333"
  57. v-for="(item,index) in provincesKeyList"
  58. :key="index"
  59. @click="provinceKeyClick(item,index)"
  60. hover-class="board-active"
  61. hover-start-time="0"
  62. hover-stay-time="80">
  63. {{item}}
  64. </view>
  65. </view>
  66. </template>
  67. <!--数字键盘-->
  68. <template v-if="!provinceBoardShow">
  69. <view class="number-keyboard flex between">
  70. <template>
  71. <view
  72. class="td td-num color-333"
  73. :class="numberIsDis ? 'board-active' : ''"
  74. v-for="(item,index) in numberKeyList"
  75. :key="index"
  76. @click="numberKeyClick(item,index)"
  77. :hover-class="numberIsDis ? '' : 'board-active'"
  78. hover-start-time="0"
  79. hover-stay-time="80">
  80. {{item}}
  81. </view>
  82. </template>
  83. </view>
  84. </template>
  85. <!--字母键盘-->
  86. <template v-if="!provinceBoardShow">
  87. <view class="english-keyboard flex between">
  88. <template>
  89. <view
  90. class="td td-num color-333"
  91. :class="englishIsDis ? 'board-active' : ''"
  92. v-for="(item,idx) in englishKeyOneList"
  93. :key="idx"
  94. @click="englishKeyClick(item,idx)"
  95. :hover-class="englishIsDis ? '' : 'board-active'"
  96. hover-start-time="0"
  97. hover-stay-time="80">
  98. {{item}}
  99. </view>
  100. </template>
  101. </view>
  102. <!-- 最后一行 -->
  103. <view class="english-keyboard flex englishtTwo">
  104. <template>
  105. <view
  106. class="td td-num color-333"
  107. :class="englishIsDis ? 'board-active' : ''"
  108. v-for="(item,index) in englishKeyTwoList"
  109. :key="index"
  110. @click="englishKeyClick(item,index)"
  111. :hover-class="englishIsDis ? '' : 'board-active'"
  112. hover-start-time="0"
  113. hover-stay-time="80">
  114. {{item}}
  115. </view>
  116. </template>
  117. <!-- 挂字键 -->
  118. <template v-if="vehicleType === 'trailer'">
  119. <view
  120. @click="trailerFiledClick('挂')"
  121. class="td td-num color-333"
  122. :class="trailerFiledIsDis ? 'board-active' : ''"
  123. :hover-class="trailerFiledIsDis ? '' : 'board-active'"
  124. hover-start-time="0"
  125. hover-stay-time="80"
  126. >挂</view>
  127. </template>
  128. </view>
  129. </template>
  130. <!--清除按钮-->
  131. <view
  132. @click="backspace"
  133. class="delete flex"
  134. hover-class="board-active"
  135. hover-start-time="0"
  136. hover-stay-time="80">
  137. <!-- <image class="deleteImg" src="../../static/my/clear.png" /> -->
  138. <u-icon name="backspace" size='32'></u-icon>
  139. </view>
  140. </view>
  141. </view>
  142. </view>
  143. </u-popup>
  144. </view>
  145. </template>
  146. <script>
  147. export default {
  148. name: 'carKeyboard',
  149. props: {
  150. // 组件显示
  151. show: {
  152. type: Boolean,
  153. default: false
  154. },
  155. // 初始传入车牌号
  156. vehicleNo: {
  157. type: String,
  158. default: ''
  159. },
  160. /**
  161. * 车辆牌照类型 默认挂车
  162. * trailer 挂车
  163. * car 汽车
  164. */
  165. vehicleType: {
  166. type: String,
  167. default: 'trailer'
  168. },
  169. // 是否展示新能源切换按钮
  170. checkboxShow: {
  171. type: Boolean,
  172. default: true,
  173. }
  174. },
  175. data() {
  176. return {
  177. /**
  178. * currIndex 初始化为零 控制确定按钮高亮
  179. * currentFocus 初始化为零 控制输入框高亮
  180. */
  181. numberIsDis: true, // 输入键盘不可点击 true为不可点击
  182. englishIsDis: false, // 字母键盘可点击
  183. provinceBoardShow: true, // 省键盘
  184. isNewEnergy: false, // 是否新能源
  185. checkboxList: [],
  186. trailerFiledIsDis: true, // 挂字禁用
  187. provincesKeyList: '京津冀晋蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼渝川贵云藏陕甘青宁新',
  188. numberKeyList: '0123456789',
  189. englishKeyOneList: 'ABCDEFGHJKLMNPQRSTUV',
  190. englishKeyTwoList: 'WXYZ',
  191. currentFocus: 0,
  192. currIndex: 0,
  193. plateLimit: 7, // 车牌号位数
  194. codeList: [],
  195. // codeReset: []
  196. };
  197. },
  198. watch: {
  199. show: {
  200. handler(val) {
  201. this.initData()
  202. },
  203. immediate: true,
  204. }
  205. },
  206. computed: {
  207. confirmBtnFocus() {
  208. return this.currIndex === this.codeList.length || this.currIndex == 0
  209. }
  210. },
  211. methods: {
  212. // 省份键盘
  213. provinceKeyClick(val,index) {
  214. this.currentFocus++;
  215. this.currIndex++;
  216. this.codeList[0].value = val;
  217. this.provinceBoardShow = false;
  218. this.numberIsDis = true;
  219. this.englishIsDis = false;
  220. },
  221. // 数字键盘
  222. numberKeyClick(val,idx) {
  223. if(this.numberIsDis) return
  224. if (this.currIndex >= this.codeList.length) return
  225. this.currIndex++;
  226. this.currentFocus = this.currIndex;
  227. this.codeList[this.currIndex - 1].value = val;
  228. if(this.vehicleType === 'trailer') {
  229. this.setTrailerKeyboardDis()
  230. }
  231. },
  232. // 字母键盘
  233. englishKeyClick(val,idx) {
  234. if(this.englishIsDis) return
  235. if (this.currIndex >= this.codeList.length) return
  236. this.currIndex++;
  237. this.currentFocus = this.currIndex;
  238. this.codeList[this.currIndex - 1].value = val;
  239. if(this.currIndex === 2) this.numberIsDis = false;
  240. if(this.vehicleType === 'trailer') {
  241. this.setTrailerKeyboardDis()
  242. }
  243. },
  244. // 挂字点击
  245. trailerFiledClick(val) {
  246. if(this.trailerFiledIsDis) return
  247. if (this.currIndex > this.codeList.length - 1) return
  248. this.currIndex++;
  249. this.currentFocus = this.currIndex + 1;
  250. this.codeList[this.currIndex - 1].value = val;
  251. },
  252. // 设置挂车键盘禁用(最后一个只能选择挂)
  253. setTrailerKeyboardDis() {
  254. if(this.currIndex + 1 === this.codeList.length) {
  255. this.numberIsDis = true;
  256. this.englishIsDis = true;
  257. this.trailerFiledIsDis = false;
  258. }
  259. },
  260. // 退格
  261. backspace() {
  262. if (!this.currIndex) return
  263. this.currIndex--;
  264. this.codeList[this.currIndex].value = '';
  265. this.currentFocus = this.currIndex;
  266. this.provinceBoardShow = this.currIndex === 0;
  267. if(this.currIndex === 1) this.numberIsDis = true;
  268. if(this.vehicleType === "trailer" && this.currIndex === this.codeList.length - 2) {
  269. this.numberIsDis = false;
  270. this.englishIsDis = false;
  271. this.trailerFiledIsDis = true;
  272. }
  273. },
  274. // 关闭
  275. closeKeyboard(e) {
  276. this.$emit('update:show',false)
  277. this.$emit('close')
  278. },
  279. // 确定
  280. confirmKeyboard(e) {
  281. if (this.currIndex < this.codeList.length && this.currIndex!=0) return
  282. let plate = ''
  283. this.codeList.map(item => (plate += item.value))
  284. this.$emit('confirm', plate)
  285. this.closeKeyboard()
  286. },
  287. // 是否新能源车牌checkbox change
  288. checkboxChange(val) {
  289. console.log(val,'checkbox change');
  290. this.isNewEnergy = val.length ? true : false;
  291. if(val.length) {
  292. this.codeList.push({value: ''})
  293. // this.codeReset.push({value: ''})
  294. } else {
  295. this.codeList.splice(this.codeList.length - 1,1)
  296. // this.codeReset.splice(this.codeList.codeReset - 1,1)
  297. let vehicleNo = "";
  298. this.codeList.map(item => (vehicleNo += item.value))
  299. if(vehicleNo.length === this.codeList.length && this.currIndex > this.codeList.length) {
  300. this.currIndex--;
  301. this.currentFocus--
  302. }
  303. }
  304. },
  305. initData() {
  306. console.log('initData',this.isNewEnergy);
  307. console.log(this.checkboxList);
  308. let temp = []
  309. // let reset = []
  310. const vehicleNoTrim = this.vehicleNo.trim()
  311. const Leng = vehicleNoTrim ? vehicleNoTrim.length : 0;
  312. // 新能源checkbox回显
  313. this.isNewEnergy = Leng > 7 ? true : false;
  314. this.checkboxList = Leng > 7 ? [{text:'新能源车',value:1}] : []
  315. if (Leng) {
  316. let arr = vehicleNoTrim.split('')
  317. arr.forEach(item => {
  318. temp.push({value: item})
  319. // reset.push({value: ''})
  320. })
  321. } else {
  322. // 初始化设置数据
  323. for (let index = 0; index < this.plateLimit; index++) {
  324. temp.push({value: ''})
  325. // reset.push({value: ''})
  326. }
  327. }
  328. // 解决车牌号回显位数不够问题
  329. if(Leng > 0 && Leng < 7) {
  330. let num = 7 - Leng;
  331. for(let i = 0; i < num; i++) {
  332. temp.push({value: ''})
  333. }
  334. }
  335. // 禁用设置
  336. this.isNewEnergy = Leng > 7 ? true : false;
  337. this.provinceBoardShow = Leng > 0 ? false : true;
  338. this.numberIsDis = Leng < 2 ? true : false;
  339. this.englishIsDis = false;
  340. if(this.vehicleType === 'trailer') {
  341. if(Leng >= 6) {
  342. this.numberIsDis = true;
  343. this.englishIsDis = true;
  344. }
  345. this.trailerFiledIsDis = Leng < 6 ? true: false;
  346. }
  347. this.codeList = temp;
  348. // this.codeReset = reset;
  349. this.currentFocus = Leng;
  350. this.currIndex = vehicleNoTrim ? vehicleNoTrim.length : 0;
  351. }
  352. },
  353. }
  354. </script>
  355. <style lang="scss" scoped>
  356. .flex {
  357. display: flex;
  358. }
  359. .between {
  360. justify-content: space-between;
  361. }
  362. .font-30 {
  363. font-size: 30rpx;
  364. }
  365. .color-333 {
  366. color: #333333;
  367. }
  368. .trailer-keyboard {
  369. }
  370. .keyBoard_content {
  371. z-index: 9999;
  372. position: fixed;
  373. bottom: 0;
  374. left: 0;
  375. width: 100%;
  376. height: auto;
  377. background: #fff;
  378. .top-part {
  379. width: 100%;
  380. padding: 25rpx 40rpx;
  381. height: 92rpx;
  382. justify-content: center;
  383. align-items: center;
  384. box-sizing: border-box;
  385. border-bottom: 1rpx solid #EAEAEA;
  386. margin-bottom: 15rpx;
  387. text-align: center;
  388. .close {
  389. width: 10%;
  390. font-size: 47rpx;
  391. color: #A0A0A0;
  392. }
  393. .message {
  394. font-size: 15px;
  395. width: 80%;
  396. text-align: center;
  397. font-weight: Semibold;
  398. }
  399. .confirm {
  400. width: 10%;
  401. color: #A0A0A0;
  402. font-weight: Regular;
  403. &.confirm-active {
  404. color: #27B57D;
  405. }
  406. }
  407. }
  408. .input-and-checkbox {
  409. .license {
  410. box-sizing: border-box;
  411. justify-content: space-around;
  412. margin: 72rpx 86rpx 30rpx;
  413. .edit-text {
  414. height: 80rpx;
  415. line-height: 80rpx;
  416. width: 60rpx;
  417. border: 1rpx solid #A0A0A0;
  418. border-radius: 8rpx;
  419. text-align: center;
  420. font-size: 36rpx;
  421. &.space-left {
  422. // margin-left: 30rpx;
  423. }
  424. &.border-active {
  425. border: 1rpx solid #5BCA92;
  426. }
  427. }
  428. }
  429. .checkbox-box {
  430. margin: 25rpx 86rpx 28rpx;
  431. display: flex;
  432. justify-content: flex-end;
  433. .uCheckbox {
  434. }
  435. }
  436. }
  437. .keyboard-content {
  438. width: 100%;
  439. height: 450rpx;
  440. box-sizing: border-box;
  441. position: relative;
  442. .td {
  443. font-family: "PingFangSC";
  444. font-size: 32rpx;
  445. color: #333333;
  446. font-weight: 500;
  447. margin: 12rpx 2rpx;
  448. border: 1rpx solid #E0E0E0;
  449. border-radius: 8rpx;
  450. height: 84rpx;
  451. line-height: 84rpx;
  452. text-align: center;
  453. }
  454. .province-keyboard {
  455. margin: 0 50rpx;
  456. flex-wrap: wrap;
  457. .td-nor {
  458. flex: 0 1 9%;
  459. margin-right: 3px;
  460. }
  461. }
  462. .number-keyboard {
  463. margin: 0 5rpx;
  464. .td-num {
  465. flex: 0 1 8%;
  466. }
  467. }
  468. .english-keyboard {
  469. margin: 0 5rpx;
  470. flex-wrap: wrap;
  471. &.englishtTwo {
  472. margin-left: 80rpx;
  473. .td-num {
  474. margin-right: 5px;
  475. flex: 0 1 8.8%;
  476. }
  477. }
  478. .td-num {
  479. flex: 0 1 8%;
  480. }
  481. }
  482. .board-active {
  483. box-shadow: 0 0 0 #e5e5e5;
  484. background: #e5e5e5;
  485. }
  486. .delete {
  487. width: 140rpx;
  488. height: 84rpx;
  489. text-align: center;
  490. background-color: #D8D8D8;
  491. border-radius: 8rpx;
  492. position: absolute;
  493. right: 73rpx;
  494. bottom: 32rpx;
  495. justify-content: center;
  496. align-items: center;
  497. .deleteImg {
  498. width: 48rpx;
  499. height: 48rpx;
  500. }
  501. }
  502. }
  503. }
  504. </style>