index.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. import baseComponent from '../helpers/baseComponent'
  2. import classNames from '../helpers/libs/classNames'
  3. const defaults = {
  4. prefixCls: 'wux-keyboard',
  5. className: '',
  6. titleText: '安全键盘',
  7. cancelText: '取消',
  8. inputText: '输入数字密码',
  9. showCancel: true,
  10. disorder: false,
  11. password: true,
  12. maxlength: 6,
  13. closeOnReject: true,
  14. onChange(value) {},
  15. callback(value) {},
  16. // onClose(value) {},
  17. }
  18. /**
  19. * 给指一位数组随机生成二维数组
  20. *
  21. * @param {boolean} [isRandom=false] 是否随机
  22. * @param {array} [arr=[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]] 默认数组
  23. * @returns
  24. */
  25. const upsetNums = (isRandom = false, arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]) => {
  26. if (isRandom) {
  27. const floor = Math.floor
  28. const random = Math.random
  29. const len = arr.length
  30. let i, j, temp, n = floor(len / 2) + 1
  31. while (n--) {
  32. i = floor(random() * len)
  33. j = floor(random() * len)
  34. if (i !== j) {
  35. temp = arr[i]
  36. arr[i] = arr[j]
  37. arr[j] = temp
  38. }
  39. }
  40. }
  41. let nums = []
  42. for (let i = 0; i < 4; i++) {
  43. nums.push(arr.slice(i * 3, (i + 1) * 3))
  44. }
  45. return nums
  46. }
  47. baseComponent({
  48. useFunc: true,
  49. data: defaults,
  50. computed: {
  51. classes: ['prefixCls', function(prefixCls) {
  52. const wrap = classNames(prefixCls)
  53. const hd = `${prefixCls}__hd`
  54. const bd = `${prefixCls}__bd`
  55. const label = `${prefixCls}__label`
  56. const password = `${prefixCls}__password`
  57. const input = `${prefixCls}__input`
  58. const ft = `${prefixCls}__ft`
  59. const title = `${prefixCls}__title`
  60. const numbers = `${prefixCls}__numbers`
  61. const number = `${prefixCls}__number`
  62. const text = `${prefixCls}__text`
  63. const hover = `${prefixCls}__text--hover`
  64. return {
  65. wrap,
  66. hd,
  67. bd,
  68. label,
  69. password,
  70. input,
  71. ft,
  72. title,
  73. numbers,
  74. number,
  75. text,
  76. hover,
  77. }
  78. }],
  79. },
  80. methods: {
  81. /**
  82. * 隐藏
  83. */
  84. hide() {
  85. this.$$setData({ in: false })
  86. },
  87. /**
  88. * 上拉键盘组件
  89. * @param {Object} opts 配置项
  90. * @param {String} opts.className 自定义类名
  91. * @param {String} opts.titleText 标题
  92. * @param {String} opts.cancelText 取消按钮的文字
  93. * @param {String} opts.inputText 提示文本
  94. * @param {Boolean} opts.showCancel 是否显示取消按钮
  95. * @param {Boolean} opts.disorder 是否打乱键盘
  96. * @param {Boolean} opts.password 是否密码类型
  97. * @param {Number} opts.maxlength 最大输入长度,设置为 -1 的时候不限制最大长度
  98. * @param {Boolean} opts.closeOnReject Promise 返回 reject 时关闭组件
  99. * @param {Function} opts.onChange change 事件触发的回调函数
  100. * @param {Function} opts.callback 输入完成后的回调函数
  101. * @param {Function} opts.onClose 输入完成后的回调函数,优先级高于 callback
  102. */
  103. show(opts = {}) {
  104. const nums = upsetNums(opts.disorder)
  105. const maxlength = opts.maxlength <= 0 ? -1 : opts.maxlength
  106. const keys = maxlength !== -1 ? [...new Array(maxlength || defaults.maxlength)].map(() => 1) : []
  107. const options = this.$$mergeOptionsAndBindMethods(Object.assign({ nums, keys, value: '' }, defaults, opts))
  108. this.$$setData({ in: true, ...options })
  109. return this.hide.bind(this)
  110. },
  111. /**
  112. * 增加
  113. */
  114. increase(e) {
  115. const dataset = e.currentTarget.dataset
  116. const nextValue = String(dataset.value)
  117. const { value, maxlength } = this.data
  118. if (value.length >= maxlength && maxlength !== -1) return
  119. this.updateValue(value + nextValue)
  120. },
  121. /**
  122. * 减少
  123. */
  124. decrease(e) {
  125. const { value } = this.data
  126. if (value.length === 0) return
  127. this.updateValue(value.substr(0, value.length - 1))
  128. },
  129. /**
  130. * 更新
  131. */
  132. updateValue(value = '') {
  133. this.$$setData({ value })
  134. // onChange
  135. if (typeof this.fns.onChange === 'function') {
  136. this.fns.onChange.call(this, value)
  137. }
  138. // onClose
  139. if (value.length === this.data.maxlength) {
  140. const preCloseCallback = this.fns.onClose || this.fns.callback
  141. const resolveFn = this.hide.bind(this)
  142. const rejectFn = this.data.closeOnReject ? resolveFn : function reject() {}
  143. if (preCloseCallback && typeof preCloseCallback === 'function') {
  144. const preCloseCallbackResult = preCloseCallback.call(this, value)
  145. if (typeof preCloseCallbackResult === 'object') {
  146. if (preCloseCallbackResult.closePromise) {
  147. preCloseCallbackResult.closePromise.then(resolveFn, rejectFn)
  148. } else {
  149. preCloseCallbackResult.then(resolveFn, rejectFn)
  150. }
  151. } else if (preCloseCallbackResult !== false) {
  152. resolveFn()
  153. }
  154. } else {
  155. resolveFn()
  156. }
  157. }
  158. },
  159. },
  160. })