VKeyboard.vue 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. <template>
  2. <view v-if="showKeyboard"
  3. :class="['enl-size', digital?'enl-size_custom':'',keyboardStyle]">
  4. <view class="digit-keyboard" v-if="mode === 'digit' || digital">
  5. <view class="digit-button-box">
  6. <template v-for="(digit, index) in digits">
  7. <!-- <view :key="index" class="enl-key-button enl-digit" @tap="typing('.')" v-if="index === 9">.</view> -->
  8. <view :key="index" class="enl-key-button enl-digit" @tap="typing(digit)">
  9. <text>{{digit}}</text>
  10. </view>
  11. </template>
  12. <view class="enl-key-button enl-digit" v-if="!digital">
  13. <!-- <i class="iconfont icon-shouqijianpan enl-middle" @tap="deactivate"></i> -->
  14. <i class="iconfont icon-ABC enl-middle" v-if="!digital" @tap="typingLetter"></i>
  15. </view>
  16. </view>
  17. <view class="special-button-box">
  18. <view class="enl-key-button special-button enl-gray" @tap="backspace"><i class="iconfont icon-backspace enl-large"></i></view>
  19. <view class="enl-key-button special-button enl-gray" @tap="enter">
  20. <!-- <i class="iconfont icon-huiche enl-large"></i> -->
  21. <text>确定</text>
  22. </view>
  23. </view>
  24. </view>
  25. <view class="full-keyboard" v-else>
  26. <view class="line" v-for="(letters, index) in lines" :key="index">
  27. <view class="enl-letter enl-key-button special-key enl-gray" v-if="index === 2 && mode === 'letter'" @tap="toggleCase"><i
  28. :class="'iconfont ' + (lowercase ? 'icon-xiaoxie' : 'icon-daxie')"></i></view>
  29. <view class="enl-letter enl-key-button normal" v-for="letter in letters" @tap="typing(letter)" :key="letter">
  30. <text>{{letter}}</text>
  31. </view>
  32. <view class="enl-letter enl-key-button special-key enl-gray" v-if="index === 2" @tap="backspace"><i class="iconfont icon-backspace"></i></view>
  33. </view>
  34. <view class="line special-line">
  35. <view class="enl-letter enl-key-button swith-key enl-gray">
  36. <i class="iconfont icon-fuhao" @tap="typingSymbol" v-if="mode === 'letter'"></i>
  37. <i class="iconfont icon-ABC" @tap="typingLetter" v-if="mode === 'symbol'"></i>
  38. </view>
  39. <view class="enl-letter enl-key-button space" @tap="typing(' ')"><text class="enl-logo">spacebar</text></view>
  40. <view class="enl-letter enl-key-button swith-key enl-gray" @tap="typingDigit"><i class="iconfont icon-shuzi"></i></view>
  41. <!-- <view class="enl-letter enl-key-button swith-key enl-gray" @tap="enter">
  42. <i class="iconfont icon-huiche"></i>
  43. </view> -->
  44. </view>
  45. </view>
  46. </view>
  47. </template>
  48. <script>
  49. import {
  50. natural,
  51. order,
  52. disorder,
  53. symbols,
  54. digits,
  55. KEYBOARD_MODE
  56. } from './utils'
  57. export default {
  58. props: {
  59. //是否为纯数字键盘
  60. digital: {
  61. type: [Boolean, String],
  62. default: false
  63. },
  64. //是否无序的排序键盘
  65. disorderly: {
  66. type: [Boolean, String],
  67. default: false
  68. },
  69. pointIsShow:{
  70. type: Boolean,
  71. default: true
  72. },
  73. isEffect:{
  74. type:Boolean,
  75. default: false
  76. }
  77. /* ,
  78. value: String */
  79. },
  80. //app中不生效,不知道为什么
  81. /* model: {
  82. prop: 'value',
  83. event: 'typing'
  84. }, */
  85. computed: {
  86. keyboardStyle() {
  87. return 'v-keyboard ' + this.cls;
  88. }
  89. },
  90. data() {
  91. return {
  92. cls: '',
  93. visible: false, //是否显示
  94. showKeyboard: false, //是否隐藏
  95. digits: [], //自然数数组
  96. lines: [], //字母+数字数组
  97. lowercase: true, //是否小写输入状态
  98. mode: KEYBOARD_MODE.LETTER, //键盘模式
  99. keys: [] //键入的键值
  100. }
  101. },
  102. methods: {
  103. //大小写转换
  104. toggleCase() {
  105. this.lowercase = !this.lowercase;
  106. },
  107. //输入符号
  108. typingSymbol() {
  109. this.mode = KEYBOARD_MODE.SYMBOL;
  110. this.lines = symbols;
  111. },
  112. //输入字母
  113. typingLetter() {
  114. this.mode = KEYBOARD_MODE.LETTER;
  115. this.lines = this.disorderly ? disorder() : order;
  116. },
  117. //键入数字
  118. typingDigit() {
  119. this.mode = KEYBOARD_MODE.DIGIT;
  120. },
  121. //键盘键入
  122. typing(input) {
  123. this.keys.push(input);
  124. //app中v-model不生效,改用事件方式在外处理
  125. //this.$emit('typing', this.keys.join(''));
  126. this.$emit('typing', {
  127. backspace: false,
  128. char: input
  129. })
  130. },
  131. //退格键
  132. backspace() {
  133. if (this.keys.length) {
  134. this.keys.pop()
  135. }
  136. //this.$emit('typing', this.keys.join(''));
  137. this.$emit('typing', {
  138. backspace: true
  139. })
  140. },
  141. //键入回车
  142. enter() {
  143. //this.deactivate();
  144. this.$emit('enter');
  145. },
  146. //激活键盘
  147. activate() {
  148. // #ifdef APP-PLUS
  149. plus.key.hideSoftKeybord();
  150. // #endif
  151. this.showKeyboard = true
  152. this.$nextTick(() => {
  153. this.visible = true;
  154. })
  155. },
  156. //隐藏键盘
  157. deactivate() {
  158. this.visible = false;
  159. setTimeout(() => {
  160. this.showKeyboard = false
  161. }, 250)
  162. }
  163. },
  164. watch: {
  165. lowercase(val) {
  166. let [...temp] = this.lines;
  167. temp.forEach(line => {
  168. line.forEach((letter, index) => {
  169. line[index] = val ? letter.toLowerCase() : letter.toUpperCase();
  170. });
  171. });
  172. this.lines = temp;
  173. },
  174. visible(val) {
  175. if(this.isEffect) {
  176. this.cls = val ? 'slideup' : 'slidedown';
  177. }
  178. }
  179. },
  180. created() {
  181. this.lines = this.disorderly ? disorder() : order;
  182. this.digits = this.disorderly ? digits() : natural;
  183. if(!this.pointIsShow) {
  184. this.digits = this.digits.filter(i=>i!=='.')
  185. }
  186. }
  187. }
  188. </script>
  189. <style lang="scss" scoped>
  190. @import './css.scss'; //引入键盘样式
  191. @import './icon.css'; //引入键盘icon
  192. .iconfont {
  193. font-family: "iconfont" !important;
  194. font-size: 24rpx;
  195. font-style: normal;
  196. -webkit-font-smoothing: antialiased;
  197. -moz-osx-font-smoothing: grayscale;
  198. }
  199. .enl-size {
  200. // font-size: 24rpx;
  201. height: 100%;
  202. }
  203. .enl-size_custom {
  204. // width: 700rpx!important;
  205. }
  206. .enl-key-button {
  207. display: inline-block;
  208. overflow: hidden;
  209. // vertical-align: middle;
  210. border: 1px solid #e6e6e6;
  211. color: #333;
  212. background-color: #fff;
  213. box-shadow: 0 2px 2px rgba(230, 230, 230, .7);
  214. border-radius: 3upx;
  215. text-align: center;
  216. white-space: nowrap;
  217. user-select: none;
  218. cursor: pointer;
  219. &:active {
  220. background: #d6d6d6;
  221. scale: 0.7;
  222. }
  223. }
  224. .v-keyboard {
  225. width: 100%;
  226. position: relative;
  227. bottom: 0;
  228. left: 0;
  229. background: #f5f5f5;
  230. padding: 1% 0;
  231. height: 100%;
  232. z-index: 100;
  233. /*全键盘*/
  234. .full-keyboard {
  235. display: flex;
  236. flex-direction: column;
  237. align-items: center;
  238. height: 100%;
  239. .line {
  240. text-align: center;
  241. flex: 1;
  242. width: 100%;
  243. &:not(:last-child) {
  244. // margin-bottom: 1%;
  245. }
  246. .enl-letter {
  247. height: 95%;
  248. font-size: 20rpx;
  249. padding: 0rpx 0rpx;
  250. &:not(:last-child) {
  251. margin-right: 1%;
  252. }
  253. }
  254. .normal {
  255. // width: 1.73em;
  256. width: 9%;
  257. }
  258. .special-key {
  259. width: 9%;
  260. }
  261. }
  262. .special-line {
  263. padding: 0 1%;
  264. display: flex !important;
  265. justify-content: space-around;
  266. font-size: 24rpx;
  267. .space {
  268. flex: 1;
  269. display: flex;
  270. align-items: center;
  271. justify-content: center;
  272. }
  273. .swith-key {
  274. width: 13%;
  275. }
  276. .enl-logo {
  277. font-size: 30rpx;
  278. }
  279. }
  280. }
  281. /*数字键盘*/
  282. .digit-keyboard {
  283. display: flex;
  284. flex-direction: row;
  285. font-size: 24rpx;
  286. justify-content: center;
  287. height: 100%;
  288. .digit-button-box {
  289. padding: 0 1%;
  290. flex: 80;
  291. display: flex;
  292. align-items: center;
  293. flex-wrap: wrap;
  294. .enl-digit {
  295. width: 32%;
  296. height: 23%;
  297. // line-height: 20%;
  298. margin-bottom: 1%;
  299. // vertical-align: middle;
  300. // display: flex;
  301. // align-items: center;
  302. &:nth-child(10),
  303. &:nth-child(11),
  304. &:nth-child(12) {
  305. margin-bottom: 0;
  306. }
  307. &:not(:last-child) {
  308. margin-right: 1%;
  309. }
  310. }
  311. & .enl-key-button {
  312. display: flex;
  313. align-items: center;
  314. justify-content: center;
  315. }
  316. }
  317. .special-button-box {
  318. flex: 20;
  319. padding: 0 3% 0 0;
  320. .special-button {
  321. line-height: 20%;
  322. height: 45%;
  323. width: 100%;
  324. display: flex;
  325. align-items: center;
  326. justify-content: center;
  327. &:not(:last-child) {
  328. margin-bottom: 3%;
  329. }
  330. }
  331. }
  332. }
  333. .enl-gray {
  334. background: #e1e1e1 !important;
  335. &:active {
  336. background: #fff !important;
  337. }
  338. }
  339. .enl-large {
  340. font-size: 24rpx !important;
  341. }
  342. .enl-middle {
  343. font-size: 24rpx !important;
  344. display: block;
  345. }
  346. }
  347. </style>