tui-numberbox.vue 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. <template>
  2. <view class="tui-numberbox">
  3. <view class="tui-numbox-icon tui-icon-reduce " :class="[disabled || min>=value?'tui-disabled':'']" @tap.stop="reduce"
  4. :style="{color:iconColor,fontSize:iconSize+'rpx'}"></view>
  5. <input type="number" v-model="inputValue" :disabled="disabled" @blur="blur" class="tui-num-input" :style="{color:color,fontSize:size+'rpx',backgroundColor:backgroundColor,height:height+'rpx',minHeight:height+'rpx',width:width+'rpx'}" />
  6. <view class="tui-numbox-icon tui-icon-plus" :class="[disabled || value>=max?'tui-disabled':'']" @tap.stop="plus" :style="{color:iconColor,fontSize:iconSize+'rpx'}"></view>
  7. </view>
  8. </template>
  9. <script>
  10. export default {
  11. name: "tuiNumberbox",
  12. props: {
  13. value: {
  14. type: Number,
  15. default: 1
  16. },
  17. //最小值
  18. min: {
  19. type: Number,
  20. default: 1
  21. },
  22. //最大值
  23. max: {
  24. type: Number,
  25. default: 99
  26. },
  27. //迈步大小 1 1.1 10...
  28. step: {
  29. type: Number,
  30. default: 1
  31. },
  32. //是否禁用操作
  33. disabled: {
  34. type: Boolean,
  35. default: false
  36. },
  37. //加减图标大小 rpx
  38. iconSize: {
  39. type: Number,
  40. default: 26
  41. },
  42. iconColor: {
  43. type: String,
  44. default: "#666666"
  45. },
  46. //input 高度
  47. height: {
  48. type: Number,
  49. default: 42
  50. },
  51. //input 宽度
  52. width: {
  53. type: Number,
  54. default: 80
  55. },
  56. size: {
  57. type: Number,
  58. default: 28
  59. },
  60. //input 背景颜色
  61. backgroundColor: {
  62. type: String,
  63. default: "#F5F5F5"
  64. },
  65. //input 字体颜色
  66. color: {
  67. type: String,
  68. default: "#333"
  69. },
  70. //索引值,列表中使用
  71. index: {
  72. type: [Number, String],
  73. default: 0
  74. },
  75. //自定义参数
  76. custom: {
  77. type: [Number, String],
  78. default: 0
  79. }
  80. },
  81. created() {
  82. this.inputValue = +this.value
  83. },
  84. data() {
  85. return {
  86. inputValue: 0
  87. };
  88. },
  89. watch: {
  90. value(val) {
  91. this.inputValue = +val
  92. }
  93. },
  94. methods: {
  95. getScale() {
  96. let scale = 1;
  97. //浮点型
  98. if (!Number.isInteger(this.step)) {
  99. scale = Math.pow(10, (this.step + '').split('.')[1].length)
  100. }
  101. return scale;
  102. },
  103. calcNum: function(type) {
  104. if (this.disabled) {
  105. return
  106. }
  107. const scale = this.getScale()
  108. let num = this.value * scale
  109. let step = this.step * scale
  110. if (type === 'reduce') {
  111. num -= step
  112. } else if (type === 'plus') {
  113. num += step
  114. }
  115. let value = num / scale
  116. if (type === "plus" && value < this.min) {
  117. value = this.min
  118. } else if (type === "reduce" && value > this.max) {
  119. value = this.max
  120. }
  121. if (value < this.min || value > this.max) {
  122. return
  123. }
  124. this.handleChange(value, type)
  125. },
  126. plus: function() {
  127. this.calcNum("plus")
  128. },
  129. reduce: function() {
  130. this.calcNum("reduce")
  131. },
  132. blur: function(e) {
  133. let value = e.detail.value
  134. if (value) {
  135. if (~value.indexOf(".") && Number.isInteger(this.step)) {
  136. value = value.split(".")[0]
  137. }
  138. value = Number(value)
  139. if (value > this.max) {
  140. value = this.max
  141. } else if (value < this.min) {
  142. value = this.min
  143. }
  144. } else {
  145. value = this.min
  146. }
  147. if ((value == this.value && value != this.inputValue) || !e.detail.value) {
  148. this.inputValue = value
  149. }
  150. this.handleChange(value, "blur")
  151. },
  152. handleChange(value, type) {
  153. if (this.disabled) return;
  154. this.$emit('change', {
  155. value: value,
  156. type: type,
  157. index: this.index,
  158. custom: this.custom
  159. })
  160. }
  161. }
  162. }
  163. </script>
  164. <style scoped>
  165. @font-face {
  166. font-family: 'numberbox';
  167. src: url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAASQAA0AAAAABtwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAAEdAAAABoAAAAciBpnRUdERUYAAARUAAAAHgAAAB4AKQALT1MvMgAAAZwAAABDAAAAVjxzSINjbWFwAAAB9AAAAEYAAAFK5zLpOGdhc3AAAARMAAAACAAAAAj//wADZ2x5ZgAAAkgAAACHAAAAnIfIEjxoZWFkAAABMAAAAC8AAAA2FZWEOWhoZWEAAAFgAAAAHAAAACQH3gOFaG10eAAAAeAAAAARAAAAEgwAAAFsb2NhAAACPAAAAAwAAAAMADAATm1heHAAAAF8AAAAHwAAACABEAAobmFtZQAAAtAAAAFJAAACiCnmEVVwb3N0AAAEHAAAAC0AAABV/+8iFXjaY2BkYGAA4gVmC5Tj+W2+MnCzMIDATWsFOQT9v5GFgbkeyOVgYAKJAgDrogf+AHjaY2BkYGBu+N/AEMPCAAJAkpEBFbAAAEcKAm142mNgZGBgYGWQYQDRDAxMQMwFhAwM/8F8BgALpAE5AHjaY2BkYWCcwMDKwMDUyXSGgYGhH0IzvmYwYuQAijKwMjNgBQFprikMDs9Yn01kbvjfwBDD3MDQABRmBMkBAOXpDHEAeNpjYYAAFghmZGAAAACdAA4AAAB42mNgYGBmgGAZBkYGEHAB8hjBfBYGDSDNBqQZGZiesT6b+P8/AwOElvwnWQxVDwSMbAxwDiMTkGBiQAWMDMMeAABRZwszAAAAAAAAAAAAAAAwAE542iWKQQrCMBBF5xNpd0pQ7EIoTEnahSCTUNqdWz2A9TrieXKeXCc1qcPn/zfzh0BYv2pVH7oQgbvqdG5Yt/DTrNlPYz+wHvuuqhFSME4sFshTgKUsKfhH5lg8BSul3i5bS3mQdd0RIh2IjnvUrkXDd8zuhuFt86tY9fonIsSYgsXpB+cCGosAeNp9kD1OAzEQhZ/zByQSQiCoXVEA2vyUKRMp9Ailo0g23pBo1155nUg5AS0VB6DlGByAGyDRcgpelkmTImvt6PObmeexAZzjGwr/3yXuhBWO8ShcwREy4Sr1F+Ea+V24jhY+hRvUf4SbuFUD4RYu1BsdVO2Eu5vSbcsKZxgIV3CKJ+Eq9ZVwjfwqXMcVPoQb1L+EmxjjV7iFa2WpDOFhMEFgnEFjig3jAjEcLJIyBtahOfRmEsxMTzd6ETubOBso71dilwMeaDnngCntPbdmvkon/mDLgdSYbh4FS7YpjS4idCgbXyyc1d2oc7D9nu22tNi/a4E1x+xRDWzU/D3bM9JIbAyvkJI18jK3pBJTj2hrrPG7ZynW814IiU68y/SIx5o0dTr3bmniwOLn8owcfbS5kj33qBw+Y1kIeb/dTsQgil2GP5PYcRkAAAB42mNgYoAALjDJyIAOWMGiTIxMjMwiWZmJQJRXVQoigTgjMd9QGIsgAFDsEBsAAAAAAAAB//8AAgABAAAADAAAABYAAAACAAEAAwAEAAEABAAAAAIAAAAAeNpjYGBgZACCq0vUOUD0TWsFORgNADPBBE4AAA==) format('woff');
  168. font-weight: normal;
  169. font-style: normal;
  170. }
  171. .tui-numbox-icon {
  172. font-family: "numberbox" !important;
  173. font-style: normal;
  174. -webkit-font-smoothing: antialiased;
  175. -moz-osx-font-smoothing: grayscale;
  176. padding: 10rpx;
  177. }
  178. .tui-icon-reduce:before {
  179. content: "\e691";
  180. }
  181. .tui-icon-plus:before {
  182. content: "\e605";
  183. }
  184. .tui-numberbox {
  185. display: -webkit-inline-flex;
  186. display: inline-flex;
  187. align-items: center;
  188. }
  189. .tui-num-input {
  190. text-align: center;
  191. margin: 0 12rpx;
  192. font-weight: 400;
  193. }
  194. .tui-disabled {
  195. color: #ededed !important;
  196. }
  197. </style>