FullKeyboard.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. <template>
  2. <div class="keyboard">
  3. <div class="keys">
  4. <div v-for="i in 40" :class="cls_of(i - 1)"
  5. :key="i" @click="press(i - 1)"
  6. @touchstart="touch_start(i - 1)" @touchend="touch_end">
  7. {{ key_of(i - 1) }}
  8. </div>
  9. </div>
  10. <div class="keys-bottom">
  11. <div class="pos-cancel" @click="cancel">取&nbsp;&nbsp;&nbsp;&nbsp;消</div>
  12. <div class="key-blank" @click="press(-1)">空&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;格</div>
  13. <div class="pos-upload" @click="submit">确&nbsp;&nbsp;&nbsp;&nbsp;定</div>
  14. </div>
  15. </div>
  16. </template>
  17. <script>
  18. let LongPressTimer = null;
  19. const Lower = "0123456789qwertyuiopasdfghjkl⇦⇑zxcvbnm.-", Upper = "0123456789QWERTYUIOPASDFGHJKL⇦⇓ZXCVBNM.-";
  20. export default {
  21. name: "FullKeyboard",
  22. props: {
  23. max: {
  24. type: Number,
  25. default: 0
  26. },
  27. default: {
  28. type: String,
  29. default: ""
  30. }
  31. },
  32. data() {
  33. return {
  34. upper: false,
  35. val: this.default
  36. }
  37. },
  38. methods: {
  39. cls_of(index) {
  40. return (index === 29) ? "key-btn key-btn-delete" : "key-btn key-btn-normal"
  41. },
  42. key_of(index) {
  43. return this.upper ? Upper[index] : Lower[index];
  44. },
  45. press(index) {
  46. if (index === -1) { // blank
  47. if (this.max > 0 && this.val.length >= this.max) return;
  48. this.val += " ";
  49. } else if (index === 29) { // delete
  50. this.val = this.val.slice(0, -1);
  51. } else if (index === 30) { // upper
  52. this.upper = !this.upper;
  53. } else { // normal
  54. if (this.max > 0 && this.val.length >= this.max) return;
  55. this.val += this.upper ? Upper[index] : Lower[index];
  56. }
  57. },
  58. touch_start(index) {
  59. if (index === 29) {
  60. if (LongPressTimer !== null) clearInterval(LongPressTimer);
  61. LongPressTimer = setInterval(() => {
  62. if (this.val === "") {
  63. clearInterval(LongPressTimer);
  64. LongPressTimer = null;
  65. return;
  66. }
  67. this.val = this.val.slice(0, -1);
  68. }, 100);
  69. } else if (index !== 30) {
  70. if (LongPressTimer !== null) clearInterval(LongPressTimer);
  71. LongPressTimer = setInterval(() => {
  72. if (this.max > 0 && this.val.length >= this.max) {
  73. clearInterval(LongPressTimer);
  74. LongPressTimer = null;
  75. return;
  76. }
  77. this.val += this.upper ? Upper[index] : Lower[index];
  78. }, 100);
  79. }
  80. },
  81. touch_end() {
  82. if (LongPressTimer !== null) clearInterval(LongPressTimer);
  83. },
  84. cancel() {
  85. this.$emit("cancel");
  86. },
  87. submit() {
  88. this.$emit("submit", this.val);
  89. }
  90. },
  91. watch: {
  92. val(v) {
  93. this.$emit("change", v);
  94. }
  95. }
  96. }
  97. </script>
  98. <style scoped>
  99. .keyboard {
  100. width: 100%;
  101. font-size: 1.1em;
  102. font-weight: bold;
  103. box-sizing: border-box;
  104. padding: 10px 20px;
  105. background-color: white;
  106. border-top-left-radius: 4px;
  107. border-top-right-radius: 4px;
  108. }
  109. .keys {
  110. width: 100%;
  111. display: flex;
  112. flex-wrap: wrap;
  113. justify-content: space-between;
  114. align-items: center;
  115. margin-bottom: 4px;
  116. }
  117. .key-btn {
  118. width: 9.5%;
  119. height: 80px;
  120. display: flex;
  121. cursor: pointer;
  122. margin-bottom: 4px;
  123. justify-content: center;
  124. align-items: center;
  125. font-size: 1.2em;
  126. border: 1px solid lightgray;
  127. border-radius: 4px;
  128. background-color: ghostwhite;
  129. }
  130. .key-btn-normal {
  131. color: #122334;
  132. }
  133. .key-btn-delete {
  134. color: red;
  135. }
  136. .keys-bottom {
  137. width: 100%;
  138. display: flex;
  139. justify-content: space-between;
  140. align-items: center;
  141. margin-top: 11px;
  142. }
  143. .pos-cancel, .pos-upload, .key-blank {
  144. height: 60px;
  145. display: flex;
  146. justify-content: center;
  147. align-items: center;
  148. border-radius: 4px;
  149. cursor: pointer;
  150. }
  151. .pos-cancel {
  152. width: 20%;
  153. border: 1px solid #AA0123;
  154. color: dimgray;
  155. }
  156. .pos-upload {
  157. width: 20%;
  158. border: 1px solid deepskyblue;
  159. background-color: lightskyblue;
  160. color: black;
  161. }
  162. .key-blank {
  163. width: 50%;
  164. border: 1px solid black;
  165. color: #122334;
  166. }
  167. </style>