wasterIDKeyBoard.vue 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. <template>
  2. <div>
  3. <div @click="closeByClickOverlay()" v-if="_overlay" class="back-bord" />
  4. <div @click="open()" ref="inputBlock">
  5. <a-input v-model="inputValue" style="width: 280px" size="large" allowClear
  6. ref="identityCard"></a-input>
  7. </div>
  8. <!--键盘-->
  9. <transition name="keybordSlide">
  10. <div v-if="visible" class="keybord-wrap">
  11. <header class="keybord-header">
  12. <span @click.stop="cancel()" style="color: red;font-size: large">取消</span>
  13. <span v-if="previewOnKeyboard" :class="['preview', { 'new-energy': newEnergy }]">{{ inputValue}}</span>
  14. <span :class="[{ gray: inputValue.length !== 18}]" style="font-weight:bold;font-size: large" @click.stop="submit()">完成</span>
  15. </header>
  16. <div class="keybord-keys">
  17. <ul class="keybord-keys-word-wrap" >
  18. <li @click.stop="inputWord(item)" class="button" v-for="item in numberList.slice(0, 3)" :key="item">
  19. {{ item }}
  20. </li>
  21. </ul>
  22. <ul class="keybord-keys-word-wrap" >
  23. <li @click.stop="inputWord(item)" class="button" v-for="item in numberList.slice(3, 6)" :key="item">
  24. {{ item }}
  25. </li>
  26. </ul>
  27. <ul class="keybord-keys-word-wrap" >
  28. <li @click.stop="inputWord(item)" class="button" v-for="item in numberList.slice(6, 9)" :key="item">
  29. {{ item }}
  30. </li>
  31. </ul>
  32. <div class="keybord-keys-bottom">
  33. <div @click.stop="toggle()" class="big-button">
  34. {{ keybordType }}
  35. </div>
  36. <ul class="keybord-keys-bottom-line">
  37. <li @click.stop="inputWord(item)" class="button" v-for="item in numberList.slice(9, 11)" :key="item">
  38. {{ item }}
  39. </li>
  40. </ul>
  41. <div @click.stop="deleteOne()" class="big-button">
  42. <slot name="backspace">
  43. <span class="icon-delete">⇦</span>
  44. </slot>
  45. </div>
  46. </div>
  47. </div>
  48. </div>
  49. </transition>
  50. </div>
  51. </template>
  52. <script>
  53. export default {
  54. name: 'waster-id-key-board',
  55. props: {
  56. value: {
  57. type: String,
  58. default: ''
  59. },
  60. openKeyboardOnInit: {
  61. type: Boolean,
  62. default: false
  63. },
  64. closeOnClickOverlay: {
  65. type: Boolean,
  66. default: true
  67. },
  68. overlay: {
  69. type: Boolean,
  70. default: true
  71. },
  72. previewOnKeyboard: {
  73. type: Boolean,
  74. default: true
  75. },
  76. checkInputBlocked: {
  77. type: Boolean,
  78. default: false
  79. },
  80. readonly: {
  81. type: Boolean,
  82. default: false
  83. }
  84. },
  85. data: function() {
  86. return {
  87. placeholderDom: null,
  88. keybordType: '数字',
  89. inputValue: "",
  90. visible: false,
  91. numberList: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 'X']
  92. }
  93. },
  94. computed: {
  95. _overlay() {
  96. return this.visible && this.overlay
  97. },
  98. // judgeList() {
  99. // if (this.keybordType === 'ABC') {
  100. // return this.abcList.slice(29, 36)
  101. // } else if (this.keybordType === '英') {
  102. // return this.carNo2List.slice(21, 26)
  103. // } else {
  104. // return this.wordList.slice(30, 37)
  105. // }
  106. // },
  107. newEnergy() {
  108. return this.inputValue.length === 18
  109. }
  110. },
  111. methods: {
  112. init() {
  113. this.visible = this.openKeyboardOnInit
  114. },
  115. isActive(index) {
  116. return this.inputValue.length === index - 1
  117. },
  118. // 键盘类型切换
  119. toggle() {
  120. },
  121. // 文字输入
  122. inputWord(word) {
  123. if (this.inputValue.length < 18) return
  124. this.inputValue += word
  125. this.$emit('submit', this.inputValue)
  126. },
  127. // 删除一个字符
  128. deleteOne() {
  129. this.inputValue = this.inputValue.slice(0, -1)
  130. },
  131. closeByClickOverlay() {
  132. if (!this.closeOnClickOverlay) return
  133. this.cancel()
  134. },
  135. // 取消
  136. cancel() {
  137. this.visible = false
  138. // this.inputValue = []
  139. this.$emit('cancel', this.inputValue="")
  140. },
  141. // 完成
  142. submit() {
  143. if (this.inputValue.length < 18) return
  144. this.visible = false
  145. this.$emit('submit', this.inputValue)
  146. },
  147. // 打开键盘
  148. open() {
  149. if (this.readonly) return
  150. this.visible = true
  151. },
  152. // 判断展示框是否被键盘挡住
  153. checkInputLocation(visible) {
  154. if (!this.checkInputBlocked) return
  155. if (visible) {
  156. const clientHeight = document.documentElement.clientHeight
  157. const scrollHeight = document.documentElement.scrollHeight
  158. const inputTopHeight = this.$refs.inputBlock.getBoundingClientRect().top
  159. const inputHeight = this.$refs.inputBlock.scrollHeight
  160. //如果键盘被挡住,并且页面没有滚动条
  161. if (inputHeight + 250 + inputTopHeight >= clientHeight && scrollHeight === clientHeight) {
  162. this.placeholderDom.style.display = 'block'
  163. }
  164. //键盘唤醒并且键盘挡住输入框,同时页面无滚动条时,占位块展示出来从而使页面可以通过scrllTo()来滚动
  165. window.scrollTo(0, 250)
  166. } else {
  167. document.body.scrollIntoView({
  168. block: 'start',
  169. behavior: 'smooth'
  170. })
  171. this.placeholderDom.style.display = 'none'
  172. }
  173. },
  174. createPlaceholderDom() {
  175. if (!this.checkInputBlocked) return
  176. this.placeholderDom = document.createElement('div')
  177. this.placeholderDom.className = 'placeholder'
  178. this.placeholderDom.style.cssText = 'height: 260px;width: 100%;background: red;opacity:0'
  179. this.placeholderDom.style.display = 'none'
  180. document.body.appendChild(this.placeholderDom)
  181. }
  182. },
  183. created() {
  184. this.init()
  185. this.createPlaceholderDom()
  186. },
  187. watch: {
  188. value(value = '') {
  189. },
  190. inputValue(key) {
  191. },
  192. visible(bool) {
  193. this.checkInputLocation(bool)
  194. }
  195. }
  196. }
  197. </script>
  198. <style scoped lang="less">
  199. @backBordZIndex: 980511;
  200. .back-bord {
  201. width: 100vw;
  202. overflow-y: scroll;
  203. height: calc(100vh + 350px);
  204. position: fixed;
  205. top: 0;
  206. left: 0;
  207. z-index: @backBordZIndex;
  208. background-color: rgba(0, 0, 0, 0.1);
  209. }
  210. .gray {
  211. color: rgb(173, 171, 171);
  212. }
  213. .data-show {
  214. position: relative;
  215. width: 100%;
  216. column-count: 8;
  217. column-gap: 2px;
  218. min-width: 190px;
  219. max-width: 450px;
  220. .data-show-block {
  221. display: flex;
  222. height: 0;
  223. align-items: center;
  224. justify-content: center;
  225. border: 1px solid #dcdfe6;
  226. padding: 50% 0;
  227. color: #323233;
  228. font-size: 18px;
  229. border-radius: 4px;
  230. }
  231. .active {
  232. outline: none;
  233. border: 1px solid #409eff;
  234. }
  235. .new-energy {
  236. border-color: #67c23a;
  237. }
  238. }
  239. .keybord-wrap {
  240. position: fixed;
  241. z-index: @backBordZIndex + 1;
  242. bottom: 0;
  243. left: 0;
  244. width: 100%;
  245. height: 350px;
  246. background: #e7e8eb;
  247. .keybord-header {
  248. padding: 0 15px;
  249. height: 60px;
  250. line-height: 60px;
  251. display: flex;
  252. justify-content: space-between;
  253. background: #f0f0f0;
  254. .preview {
  255. color: #409eff;
  256. }
  257. .new-energy {
  258. color: #67c23a;
  259. }
  260. }
  261. .keybord-keys {
  262. padding: 5px 5px 15px 5px;
  263. box-sizing: border-box;
  264. .keybord-keys-word-wrap {
  265. list-style: none;
  266. padding: 0;
  267. margin: 0;
  268. column-count: 3;
  269. column-gap: 5px;
  270. }
  271. .keybord-keys-bottom {
  272. display: flex;
  273. justify-content: space-between;
  274. .keybord-keys-bottom-line {
  275. width: 100%;
  276. margin: 0;
  277. padding: 0 5px;
  278. list-style: none;
  279. column-count: 2;
  280. column-gap: 5px;
  281. }
  282. }
  283. }
  284. }
  285. .button {
  286. &:active {
  287. background: #bbbbbb;
  288. }
  289. text-align: center;
  290. line-height: 60px;
  291. height: 60px;
  292. border-radius: 5px;
  293. background: #fff;
  294. color: black;
  295. margin-bottom: 7px;
  296. }
  297. .big-button {
  298. &:active {
  299. background: #177ce2;
  300. }
  301. width: 40vw;
  302. height: 60px;
  303. background: #1989fa;
  304. display: flex;
  305. justify-content: center;
  306. align-items: center;
  307. border-radius: 5px;
  308. color: white;
  309. .icon-delete {
  310. font-size: 20px;
  311. }
  312. }
  313. .keybordSlide-enter-active,
  314. .keybordSlide-leave-active {
  315. transition: all 0.2s linear;
  316. transform: translateY(0px);
  317. }
  318. .keybordSlide-enter, .keybordSlide-leave-to /* .keybordSlide-leave-active below version 2.1.8 */ {
  319. transform: translateY(250px);
  320. }
  321. </style>