xm-keyboard-box.vue 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. <template>
  2. <view class="xm-keyboard-box">
  3. <view class="xm-keyboard-box-line" v-for="(line, li) in lines[mode]" :key="li" :style="{
  4. marginLeft: diffSize(line.diff) + 'px',
  5. marginRight: diffSize(line.diff) / -1 + 'px',
  6. }">
  7. <view v-for="(item, index) in line.list" :key="index" class="xm-keyboard-box-item" :class="{
  8. 'xm-keyboard-box-item-empty': item == '',
  9. 'xm-keyboard-box-item-disable': disable.indexOf(item) != -1,
  10. }" :style="{
  11. width: btnWidth + 'px',
  12. height: btnHeight + 'px'
  13. }" @click="toClick(item)">
  14. {{ item }}
  15. </view>
  16. </view>
  17. <view class="xm-keyboard-box-line xm-keyboard-box-toolbar">
  18. <view v-if="showCancelBtn" class="xm-keyboard-box-item xm-keyboard-box-btn xm-keyboard-box-btn-cancel" :style="{
  19. marginRight: btnWidth / ratio + 'px',
  20. height: btnHeight + 'px'
  21. }" @click="toCancel()">取消</view>
  22. <view class="xm-keyboard-box-item xm-keyboard-box-btn xm-keyboard-box-btn-clear" :style="{
  23. marginRight: btnWidth / ratio + 'px',
  24. height: btnHeight + 'px'
  25. }" @click="toClear()">清空</view>
  26. <view class="xm-keyboard-box-item xm-keyboard-box-btn-over" :style="{
  27. marginRight: btnWidth / ratio + 'px',
  28. height: btnHeight + 'px'
  29. }" @click="toConfirm()">完成</view>
  30. </view>
  31. <view v-if="showChangeBtn" class="xm-keyboard-box-item xm-keyboard-box-btn xm-keyboard-box-btn-change" :style="{
  32. width: handlerWidth + 'px',
  33. height: btnHeight + 'px',
  34. bottom: 'calc(20px + '+btnHeight+'px)'
  35. }" @click="changeMode()">
  36. <i class="iconxmk2 icon-xm-k2-jianpan" style="font-size: 24px;"></i>
  37. </view>
  38. <view class="xm-keyboard-box-item xm-keyboard-box-btn xm-keyboard-box-btn-del" :style="{
  39. width: handlerWidth + 'px',
  40. height: btnHeight + 'px',
  41. bottom: 'calc(20px + '+btnHeight+'px)'
  42. }" @click="toDel()">
  43. <i class="iconxmk2 icon-xm-k2-backspace" style="font-size: 24px;"></i>
  44. </view>
  45. </view>
  46. </template>
  47. <script>
  48. export default {
  49. name: 'xm-keyboard-box',
  50. emits: ['add', 'del', 'confirm', 'cancel', 'clear'],
  51. props: {
  52. // 是否开启震动效果
  53. vibration: {
  54. type: Boolean,
  55. default: false
  56. },
  57. // 是否显示切换按钮
  58. showChangeBtn: {
  59. type: Boolean,
  60. default: true
  61. },
  62. // 是否显示取消按钮
  63. showCancelBtn: {
  64. type: Boolean,
  65. default: true
  66. },
  67. // 禁用某些按钮
  68. disable: {
  69. required: false,
  70. default: () => ('')
  71. },
  72. },
  73. data() {
  74. return {
  75. mode: 0,
  76. ratio: 7,
  77. max: 10,
  78. gutter: 10,
  79. btnWidth: 10,
  80. btnHeight: 10,
  81. handlerWidth: 10,
  82. lines: [
  83. [{
  84. list: ["京", "沪", "浙", "苏", "粤", "鲁", "晋", "冀", "豫", "川"],
  85. diff: 0,
  86. },
  87. {
  88. list: ["渝", "辽", "吉", "黑", "皖", "鄂", "津", "贵", "云", "桂"],
  89. diff: 0,
  90. },
  91. {
  92. list: ["琼", "青", "新", "藏", "蒙", "宁", "甘", "陕", "闽", "赣"],
  93. diff: 0,
  94. },
  95. {
  96. list: ["湘", "使", "领", "警", "学", "挂", "...", "", "", ""],
  97. diff: 3,
  98. },
  99. ],
  100. [{
  101. list: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'],
  102. diff: 0,
  103. },
  104. {
  105. list: ['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'],
  106. diff: 0,
  107. },
  108. {
  109. list: ['A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ''],
  110. diff: 1,
  111. },
  112. {
  113. list: ['Z', 'X', 'C', 'V', 'B', 'N', 'M', '', '', ''],
  114. diff: 3,
  115. },
  116. ],
  117. [{
  118. list: ['港', '澳', '台', '临', '试', '', '', '', '', ''],
  119. diff: 0,
  120. },
  121. {
  122. list: ['', '', '', '', '', '', '', '', '', ''],
  123. diff: 0,
  124. },
  125. {
  126. list: ['', '', '', '', '', '', '', '', '', ''],
  127. diff: 0,
  128. },
  129. {
  130. list: ['', '', '', '', '', '', '...', '', '', ''],
  131. diff: 3,
  132. },
  133. ],
  134. ],
  135. }
  136. },
  137. methods: {
  138. diffSize(pos) {
  139. if (pos == 0) {
  140. return 0
  141. }
  142. return (pos * this.btnWidth + pos * this.btnWidth / this.ratio) / 2
  143. },
  144. changeMode(v) {
  145. this.mode = v == void 0 ? (this.mode == 0 ? 1 : 0) : v
  146. },
  147. toClick(item) {
  148. if (item === '') {
  149. return;
  150. }
  151. if (item === '...') {
  152. this.mode = this.mode == 2 ? 0 : 2
  153. return ;
  154. }
  155. if(this.disable && this.disable.indexOf && this.disable.indexOf(item) !== -1){
  156. return ;
  157. }
  158. this.toEmit('add', item);
  159. },
  160. toDel() {
  161. this.toEmit('del');
  162. },
  163. toCancel(){
  164. this.toEmit('cancel');
  165. },
  166. toConfirm() {
  167. this.toEmit('confirm')
  168. },
  169. toClear() {
  170. this.toEmit('clear')
  171. },
  172. toEmit(type, params){
  173. this.toVibration();
  174. this.$emit(type, params);
  175. },
  176. toVibration() {
  177. if (this.vibration && uni.vibrateShort) {
  178. uni.vibrateShort();
  179. }
  180. }
  181. },
  182. mounted() {
  183. const {
  184. windowWidth
  185. } = uni.getSystemInfoSync();
  186. let _width = (windowWidth - this.gutter * 2) * this.ratio / (this.max * this.ratio + this.max - 1)
  187. this.btnWidth = _width.toFixed(2)
  188. this.btnHeight = (_width / 3 * 4).toFixed(2)
  189. this.handlerWidth = (_width * 1.5 + _width / (this.ratio * 2)).toFixed(2)
  190. }
  191. }
  192. </script>
  193. <style lang="scss" scoped>
  194. @import url(../../styles/iconfont/iconfont.css);
  195. .xm-keyboard-box {
  196. $gutter: 10px;
  197. background-color: #d4d5d9;
  198. padding: $gutter;
  199. position: relative;
  200. .xm-flex {
  201. display: flex;
  202. align-items: center;
  203. }
  204. &-line {
  205. @extend .xm-flex;
  206. justify-content: space-between;
  207. margin-bottom: $gutter;
  208. &:last-child {
  209. margin-bottom: 0;
  210. }
  211. }
  212. &-item {
  213. background-color: #FCFFFF;
  214. @extend .xm-flex;
  215. justify-content: center;
  216. border-radius: 4px;
  217. box-shadow: 0px 2px 2px #999;
  218. position: relative;
  219. &:active {
  220. background-color: rgba(0, 0, 0, 0.1);
  221. }
  222. &-empty {
  223. background-color: unset;
  224. box-shadow: unset;
  225. &:active {
  226. background-color: unset;
  227. }
  228. }
  229. &-disable{
  230. background-color: #BDBEC3;
  231. }
  232. }
  233. &-btn {
  234. background-color: #b6bcc4;
  235. &:active {
  236. background-color: rgba(182, 188, 196, 0.8);
  237. }
  238. }
  239. &-btn-del {
  240. position: absolute;
  241. right: $gutter;
  242. }
  243. &-btn-change {
  244. position: absolute;
  245. left: $gutter;
  246. }
  247. &-btn-over {
  248. // position: absolute;
  249. background-color: #f37b1d;
  250. color: #fff;
  251. &:active {
  252. background-color: rgba(243, 123, 29, 0.8);
  253. }
  254. }
  255. &-toolbar {
  256. margin-bottom: 0;
  257. .xm-keyboard-box-item {
  258. width: 100%;
  259. &:last-child {
  260. margin-right: 0 !important;
  261. }
  262. }
  263. }
  264. }
  265. </style>