tn-car-keyboard.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. <template>
  2. <view class="tn-car-keyboard-class tn-car-keyboard" @touchmove.stop.prevent="() => {}">
  3. <view class="tn-car-keyboard__grids">
  4. <view
  5. v-for="(data, index) in inputCarNumber ? endKeyBoardList : areaList"
  6. :key="index"
  7. class="tn-car-keyboard__grids__item"
  8. >
  9. <view
  10. v-for="(sub_data, sub_index) in data"
  11. :key="sub_index"
  12. class="tn-car-keyboard__grids__btn"
  13. :class="{'tn-car-keyboard__grids__btn--disabled': sub_data === 'I'}"
  14. :hover-class="sub_data !== 'I' ? 'tn-car-keyboard--hover' : ''"
  15. :hover-stay-time="100"
  16. @tap="click(index, sub_index)"
  17. >
  18. {{ sub_data }}
  19. </view>
  20. </view>
  21. <view
  22. class="tn-car-keyboard__back"
  23. hover-class="tn-hover-class"
  24. :hover-stay-time="150"
  25. @touchstart.stop="backspaceClick"
  26. @touchend="clearTimer"
  27. >
  28. <view class="tn-icon-left-arrow tn-car-keyboard__back__icon"></view>
  29. </view>
  30. <view
  31. class="tn-car-keyboard__change"
  32. hover-class="tn-car-keyboard--hover"
  33. :hover-stay-time="150"
  34. @tap="changeMode"
  35. >
  36. <text class="tn-car-keyboard__mode--zh" :class="[`tn-car-keyboard__mode--${!inputCarNumber ? 'active' : 'inactive'}`]">中</text>
  37. /
  38. <text class="tn-car-keyboard__mode--en" :class="[`tn-car-keyboard__mode--${inputCarNumber ? 'active' : 'inactive'}`]">英</text>
  39. </view>
  40. </view>
  41. </view>
  42. </template>
  43. <script>
  44. export default {
  45. name: 'tn-car-keyboard',
  46. props: {
  47. // 是否打乱键盘顺序
  48. randomEnabled: {
  49. type: Boolean,
  50. default: false
  51. },
  52. // 切换中英文输入
  53. switchEnMode: {
  54. type: Boolean,
  55. default: false
  56. }
  57. },
  58. computed: {
  59. areaList() {
  60. let data = [
  61. '京',
  62. '沪',
  63. '粤',
  64. '津',
  65. '冀',
  66. '豫',
  67. '云',
  68. '辽',
  69. '黑',
  70. '湘',
  71. '皖',
  72. '鲁',
  73. '苏',
  74. '浙',
  75. '赣',
  76. '鄂',
  77. '桂',
  78. '甘',
  79. '晋',
  80. '陕',
  81. '蒙',
  82. '吉',
  83. '闽',
  84. '贵',
  85. '渝',
  86. '川',
  87. '青',
  88. '琼',
  89. '宁',
  90. '藏',
  91. '港',
  92. '澳',
  93. '新',
  94. '使',
  95. '学',
  96. '临',
  97. '警'
  98. ]
  99. // 打乱顺序
  100. if (this.randomEnabled) data = this.$t.array.random(data)
  101. // 切割二维数组
  102. let showData = []
  103. showData[0] = data.slice(0, 10)
  104. showData[1] = data.slice(10, 20)
  105. showData[2] = data.slice(20, 30)
  106. showData[3] = data.slice(30, 37)
  107. return showData
  108. },
  109. endKeyBoardList() {
  110. let data = [
  111. 1,
  112. 2,
  113. 3,
  114. 4,
  115. 5,
  116. 6,
  117. 7,
  118. 8,
  119. 9,
  120. 0,
  121. 'Q',
  122. 'W',
  123. 'E',
  124. 'R',
  125. 'T',
  126. 'Y',
  127. 'U',
  128. 'I',
  129. 'O',
  130. 'P',
  131. 'A',
  132. 'S',
  133. 'D',
  134. 'F',
  135. 'G',
  136. 'H',
  137. 'J',
  138. 'K',
  139. 'L',
  140. 'Z',
  141. 'X',
  142. 'C',
  143. 'V',
  144. 'B',
  145. 'N',
  146. 'M'
  147. ]
  148. // 打乱顺序
  149. if (this.randomEnabled) data = this.$t.array.random(data)
  150. // 切割二维数组
  151. let showData = []
  152. showData[0] = data.slice(0, 10)
  153. showData[1] = data.slice(10, 20)
  154. showData[2] = data.slice(20, 29)
  155. showData[3] = data.slice(29, 36)
  156. return showData
  157. }
  158. },
  159. data() {
  160. return {
  161. // 标记是否输入车牌号码
  162. inputCarNumber: false,
  163. // 长按多次删除事件监听
  164. longPressDeleteTimer: null
  165. }
  166. },
  167. watch:{
  168. switchEnMode: {
  169. handler(value) {
  170. if (value) {
  171. this.inputCarNumber = true
  172. } else {
  173. this.inputCarNumber = false
  174. }
  175. },
  176. immediate: true
  177. }
  178. },
  179. methods: {
  180. // 点击键盘按钮
  181. click(i, j) {
  182. let value = ''
  183. // 根据不同模式获取不同数组的值
  184. if (this.inputCarNumber) value = this.endKeyBoardList[i][j]
  185. else value = this.areaList[i][j]
  186. // 车牌里不包含I
  187. if (value === 'I') return
  188. this.$emit('change', value)
  189. },
  190. // 修改输入模式
  191. // 中文/英文
  192. changeMode() {
  193. this.inputCarNumber = !this.inputCarNumber
  194. },
  195. // 点击退格
  196. backspaceClick() {
  197. this.$emit('backspace')
  198. this.clearTimer()
  199. this.longPressDeleteTimer = setInterval(() => {
  200. this.$emit('backspace')
  201. }, 250)
  202. },
  203. // 清空定时器
  204. clearTimer() {
  205. if (this.longPressDeleteTimer) {
  206. clearInterval(this.longPressDeleteTimer)
  207. this.longPressDeleteTimer = null
  208. }
  209. }
  210. }
  211. }
  212. </script>
  213. <style lang="scss" scoped>
  214. .tn-car-keyboard {
  215. position: relative;
  216. padding: 24rpx 0;
  217. background-color: #E6E6E6;
  218. &__grids {
  219. &__item {
  220. display: flex;
  221. flex-direction: row;
  222. align-items: center;
  223. justify-content: center;
  224. }
  225. &__btn {
  226. display: inline-flex;
  227. justify-content: center;
  228. flex: 0 0 64rpx;
  229. width: 62rpx;
  230. height: 80rpx;
  231. font-size: 38rpx;
  232. line-height: 80rpx;
  233. font-weight: 500;
  234. text-decoration: none;
  235. text-align: center;
  236. background-color: #FFFFFF;
  237. margin: 8rpx 5rpx;
  238. border-radius: 8rpx;
  239. box-shadow: 0 2rpx 0rpx $tn-box-shadow-color;
  240. &--disabled {
  241. opacity: 0.6;
  242. }
  243. }
  244. }
  245. &__back {
  246. display: flex;
  247. flex-direction: row;
  248. align-items: center;
  249. justify-content: center;
  250. position: absolute;
  251. width: 96rpx;
  252. height: 80rpx;
  253. right: 22rpx;
  254. bottom: 32rpx;
  255. background-color: #E6E6E6;
  256. border-radius: 8rpx;
  257. box-shadow: 0 2rpx 0rpx $tn-box-shadow-color;
  258. }
  259. &__change {
  260. display: flex;
  261. flex-direction: row;
  262. align-items: center;
  263. justify-content: center;
  264. position: absolute;
  265. width: 96rpx;
  266. height: 80rpx;
  267. left: 22rpx;
  268. bottom: 32rpx;
  269. line-height: 1;
  270. background-color: #FFFFFF;
  271. border-radius: 8rpx;
  272. box-shadow: 0 2rpx 0rpx $tn-box-shadow-color;
  273. }
  274. &__mode {
  275. &--zh {
  276. transform: translateY(-10rpx);
  277. }
  278. &--en {
  279. transform: translateY(10rpx);
  280. }
  281. &--active {
  282. color: $tn-main-color;
  283. font-size: 30rpx;
  284. }
  285. &--inactive {
  286. &.tn-car-keyboard__mode--zh {
  287. transform: scale(0.85) translateY(-10rpx);
  288. }
  289. }
  290. &--inactive {
  291. &.tn-car-keyboard__mode--en {
  292. transform: scale(0.85) translateY(10rpx);
  293. }
  294. }
  295. }
  296. &--hover {
  297. background-color: #E6E6E6 !important;
  298. }
  299. }
  300. </style>