uni-plate-input.vue 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. /**
  2. * @author minisola
  3. * @version 20190814
  4. */
  5. <template>
  6. <view class="so-mask">
  7. <view class="so-plate animation-scale-up">
  8. <view class="so-plate-head">
  9. <view class="so-plate-type">
  10. <radio-group @change="typeChange">
  11. <label>
  12. <radio value="1" :checked="type===1" />
  13. 普通车牌
  14. </label>
  15. <label>
  16. <radio value="2" :checked="type===2" />
  17. 新能源车牌
  18. </label>
  19. </radio-group>
  20. </view>
  21. </view>
  22. <view class="so-plate-body">
  23. <view class="so-plate-word" :class="{ active: currentInputIndex == 0 }" @tap="inputSwitch"
  24. data-index="0">
  25. <text>{{ currentInputValue[0] }}</text>
  26. </view>
  27. <view class="so-plate-word" :class="{ active: currentInputIndex == 1 }" @tap="inputSwitch"
  28. data-index="1">
  29. <text>{{ currentInputValue[1] }}</text>
  30. </view>
  31. <view class="so-plate-dot"></view>
  32. <view class="so-plate-word" :class="{ active: currentInputIndex == 2 }" @tap="inputSwitch"
  33. data-index="2">
  34. <text>{{ currentInputValue[2] }}</text>
  35. </view>
  36. <view class="so-plate-word" :class="{ active: currentInputIndex == 3 }" @tap="inputSwitch"
  37. data-index="3">
  38. <text>{{ currentInputValue[3] }}</text>
  39. </view>
  40. <view class="so-plate-word" :class="{ active: currentInputIndex == 4 }" @tap="inputSwitch"
  41. data-index="4">
  42. <text>{{ currentInputValue[4] }}</text>
  43. </view>
  44. <view class="so-plate-word" :class="{ active: currentInputIndex == 5 }" @tap="inputSwitch"
  45. data-index="5">
  46. <text>{{ currentInputValue[5] }}</text>
  47. </view>
  48. <view class="so-plate-word" :class="{ active: currentInputIndex == 6 }" @tap="inputSwitch"
  49. data-index="6">
  50. <text>{{ currentInputValue[6] }}</text>
  51. </view>
  52. <view class="so-plate-word" :class="{ active: currentInputIndex == 7 }" @tap="inputSwitch"
  53. v-if="type == 2" data-index="7">
  54. <text>{{ currentInputValue[7] }}</text>
  55. </view>
  56. </view>
  57. <view class="so-plate-foot">
  58. <view class="so-plate-keyboard" :style="{height:keyboardHeight}">
  59. <view id="keyboard dis f-wrap a-c j-c">
  60. <block v-if="inputType == 1">
  61. <view hover-class="hover" class="so-plate-key" v-for="el of provinceText" :key="el"
  62. :data-value="el" @tap="chooseKey">{{ el }}</view>
  63. </block>
  64. <block v-if="inputType == 1">
  65. <text class="so-plate-key fill-block"></text>
  66. <text class="so-plate-key fill-block"></text>
  67. </block>
  68. <block v-if="inputType >= 3">
  69. <view hover-class="hover" class="so-plate-key" v-for="el of numberText" :key="el"
  70. :data-value="el" @tap="chooseKey">{{ el }}</view>
  71. </block>
  72. <block v-if="inputType >= 2">
  73. <view hover-class="hover" class="so-plate-key" v-for="el of wordText" :key="el"
  74. :data-value="el" @tap="chooseKey">{{ el }}</view>
  75. </block>
  76. <block v-if="inputType == 3">
  77. <text v-for="el of fillBlock" :key="el.num" class="so-plate-key fill-block"></text>
  78. </block>
  79. <block v-if="inputType == 4">
  80. <view hover-class="hover" class="so-plate-key" v-for="el of lastWordText" :key="el"
  81. :data-value="el" @tap="chooseKey">{{ el }}</view>
  82. </block>
  83. <text v-if="inputType == 4" class="so-plate-key fill-block"></text>
  84. </view>
  85. </view>
  86. <view class="so-plate-btn-group">
  87. <view>
  88. <button class="so-plate-btn so-plate-btn--cancel" @tap="$emit('close')">取消</button>
  89. </view>
  90. <view>
  91. <button class="so-plate-btn so-plate-btn--delete" @tap="deleteKey">删除</button>
  92. <button class="so-plate-btn so-plate-btn--submit" @tap="exportPlate">完成</button>
  93. </view>
  94. </view>
  95. </view>
  96. </view>
  97. </view>
  98. </template>
  99. <script>
  100. export default {
  101. name: 'uni-plate-input',
  102. data() {
  103. return {
  104. type: 1, //车牌类型
  105. currentInputIndex: 0, //当前编辑的输入框
  106. currentInputValue: ['', '', '', '', '', '', ''],
  107. fillBlock: [{
  108. num: 11
  109. }, {
  110. num: 12
  111. }, {
  112. num: 13
  113. }, {
  114. num: 14
  115. }, {
  116. num: 15
  117. }, {
  118. num: 16
  119. }], //避免:key报错
  120. keyboardHeightInit: false,
  121. keyboardHeight: 'auto',
  122. provinceText: [
  123. '粤',
  124. '京',
  125. '冀',
  126. '沪',
  127. '津',
  128. '晋',
  129. '蒙',
  130. '辽',
  131. '吉',
  132. '黑',
  133. '苏',
  134. '浙',
  135. '皖',
  136. '闽',
  137. '赣',
  138. '鲁',
  139. '豫',
  140. '鄂',
  141. '湘',
  142. '桂',
  143. '琼',
  144. '渝',
  145. '川',
  146. '贵',
  147. '云',
  148. '藏',
  149. '陕',
  150. '甘',
  151. '青',
  152. '宁',
  153. '新'
  154. ],
  155. numberText: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'],
  156. wordText: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U',
  157. 'V', 'W', 'X', 'Y', 'Z'
  158. ],
  159. lastWordText: ['港', '澳', '学', '领', '警']
  160. };
  161. },
  162. props: {
  163. plate: {
  164. type: String
  165. }
  166. },
  167. computed: {
  168. //输入框类型
  169. inputType() {
  170. switch (this.currentInputIndex) {
  171. case 0:
  172. return 1;
  173. break;
  174. case 1:
  175. return 2;
  176. break;
  177. case 2:
  178. return 3;
  179. break;
  180. case 3:
  181. return 3;
  182. break;
  183. case 4:
  184. return 3;
  185. break;
  186. case 5:
  187. return 3;
  188. break;
  189. case 6:
  190. return this.type == 2 ? 3 : 4;
  191. break;
  192. case 7:
  193. return 4;
  194. break;
  195. default:
  196. return 1;
  197. break;
  198. }
  199. }
  200. },
  201. watch: {
  202. currentInputIndex: function(n, o) {
  203. if (!this.keyboardHeightInit) return
  204. this.$nextTick(() => {
  205. this.changeKeyboardHeight()
  206. })
  207. }
  208. },
  209. methods: {
  210. //车牌类型切换
  211. typeChange(e) {
  212. const {
  213. value
  214. } = e.detail;
  215. this.type = parseInt(value)
  216. this.currentInputIndex = 0
  217. if (value == 1) {
  218. this.currentInputValue = ['', '', '', '', '', '', '']
  219. } else {
  220. this.currentInputValue = ['', '', '', '', '', '', '', '']
  221. }
  222. },
  223. inputSwitch(e) {
  224. console.log(e);
  225. const {
  226. index
  227. } = e.currentTarget.dataset;
  228. this.currentInputIndex = parseInt(index);
  229. },
  230. chooseKey(e) {
  231. const {
  232. value
  233. } = e.currentTarget.dataset;
  234. this.$set(this.currentInputValue, this.currentInputIndex, value);
  235. if (this.type == 1 && this.currentInputIndex < 6) {
  236. this.currentInputIndex++
  237. }
  238. if (this.type == 2 && this.currentInputIndex < 7) {
  239. this.currentInputIndex++
  240. }
  241. },
  242. deleteKey() {
  243. this.$set(this.currentInputValue, this.currentInputIndex, '')
  244. if (this.currentInputIndex != 0) this.currentInputIndex--
  245. },
  246. exportPlate() {
  247. const plate = this.currentInputValue.join('')
  248. let err = false
  249. if (this.type === 1 && plate.length != 7) {
  250. err = true
  251. } else if (this.type === 2 && plate.length != 8) {
  252. err = true
  253. }
  254. if (err) return uni.showToast({
  255. title: '请输入完整的车牌号码',
  256. icon: 'none'
  257. })
  258. this.$emit('export', plate)
  259. },
  260. changeKeyboardHeight() {
  261. const that = this
  262. const query = uni.createSelectorQuery().in(this);
  263. query.select('#keyboard').boundingClientRect();
  264. query.exec(function(res) {
  265. if (res && res[0]) {
  266. that.keyboardHeight = res[0].height + uni.upx2px(30) + 'px'
  267. that.keyboardHeightInit = true
  268. }
  269. });
  270. }
  271. },
  272. mounted() {
  273. uni.hideKeyboard();
  274. const plateKey = this.plate.split('')
  275. if (plateKey.length === 7) {
  276. this.type = 1
  277. } else if (plateKey.length === 8) {
  278. this.type = 2
  279. }
  280. if (plateKey.length === 7 || plateKey.length === 8) {
  281. this.currentInputValue = plateKey
  282. this.currentInputIndex = plateKey.length - 1
  283. }
  284. setTimeout(() => { //在动画结束之后才开始获取
  285. this.$nextTick(() => {
  286. this.changeKeyboardHeight()
  287. })
  288. }, 500);
  289. }
  290. };
  291. </script>
  292. <style scoped>
  293. @import './uni-plate-input.css';
  294. </style>