input-number.vue 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. <template>
  2. <div class="el-input-number"
  3. :class="[
  4. size ? 'is-' + size : '',
  5. { 'is-disabled': disabled }
  6. ]"
  7. >
  8. <el-input
  9. v-model.number="currentValue"
  10. :disabled="disabled"
  11. :size="size"
  12. :class="{
  13. 'is-active': inputActive
  14. }">
  15. </el-input>
  16. <span
  17. class="el-input-number__decrease el-icon-minus"
  18. :class="{'is-disabled': minDisabled}"
  19. v-repeat-click="decrease"
  20. @mouseenter="activeInput(minDisabled)"
  21. @mouseleave="inactiveInput(minDisabled)"
  22. >
  23. </span>
  24. <span
  25. class="el-input-number__increase el-icon-plus"
  26. :class="{'is-disabled': maxDisabled}"
  27. v-repeat-click="increase"
  28. @mouseenter="activeInput(maxDisabled)"
  29. @mouseleave="inactiveInput(maxDisabled)"
  30. >
  31. </span>
  32. </div>
  33. </template>
  34. <script>
  35. import ElInput from 'element-ui/packages/input/index.js';
  36. import { once, on } from 'wind-dom/src/event';
  37. export default {
  38. name: 'ElInputNumber',
  39. props: {
  40. step: {
  41. type: Number,
  42. default: 1
  43. },
  44. max: {
  45. type: Number,
  46. default: Infinity
  47. },
  48. min: {
  49. type: Number,
  50. default: 0
  51. },
  52. value: {
  53. default: 0
  54. },
  55. disabled: Boolean,
  56. size: String
  57. },
  58. directives: {
  59. repeatClick: {
  60. bind(el, binding, vnode) {
  61. let interval = null;
  62. let startTime;
  63. const handler = () => {
  64. vnode.context[binding.expression]();
  65. };
  66. const clear = function() {
  67. if (new Date() - startTime < 100) {
  68. handler();
  69. }
  70. clearInterval(interval);
  71. interval = null;
  72. };
  73. on(el, 'mousedown', function() {
  74. startTime = new Date();
  75. once(document, 'mouseup', clear);
  76. interval = setInterval(function() {
  77. handler();
  78. }, 100);
  79. });
  80. }
  81. }
  82. },
  83. components: {
  84. ElInput
  85. },
  86. data() {
  87. // correct the init value
  88. let value = this.value;
  89. if (value < this.min) {
  90. this.$emit('input', this.min);
  91. value = this.min;
  92. }
  93. if (value > this.max) {
  94. this.$emit('input', this.max);
  95. value = this.max;
  96. }
  97. return {
  98. currentValue: value,
  99. inputActive: false
  100. };
  101. },
  102. watch: {
  103. value(val) {
  104. this.currentValue = val;
  105. },
  106. currentValue(newVal, oldVal) {
  107. if (newVal <= this.max && newVal >= this.min) {
  108. this.$emit('change', newVal);
  109. this.$emit('input', newVal);
  110. } else {
  111. this.$nextTick(() => {
  112. this.currentValue = oldVal;
  113. });
  114. }
  115. }
  116. },
  117. computed: {
  118. minDisabled() {
  119. return this.currentValue - this.step < this.min;
  120. },
  121. maxDisabled() {
  122. return this.currentValue + this.step > this.max;
  123. }
  124. },
  125. methods: {
  126. accSub(arg1, arg2) {
  127. var r1, r2, m, n;
  128. try {
  129. r1 = arg1.toString().split('.')[1].length;
  130. } catch (e) {
  131. r1 = 0;
  132. }
  133. try {
  134. r2 = arg2.toString().split('.')[1].length;
  135. } catch (e) {
  136. r2 = 0;
  137. }
  138. m = Math.pow(10, Math.max(r1, r2));
  139. n = (r1 >= r2) ? r1 : r2;
  140. return parseFloat(((arg1 * m - arg2 * m) / m).toFixed(n));
  141. },
  142. accAdd(arg1, arg2) {
  143. var r1, r2, m, c;
  144. try {
  145. r1 = arg1.toString().split('.')[1].length;
  146. } catch (e) {
  147. r1 = 0;
  148. }
  149. try {
  150. r2 = arg2.toString().split('.')[1].length;
  151. } catch (e) {
  152. r2 = 0;
  153. }
  154. c = Math.abs(r1 - r2);
  155. m = Math.pow(10, Math.max(r1, r2));
  156. if (c > 0) {
  157. var cm = Math.pow(10, c);
  158. if (r1 > r2) {
  159. arg1 = Number(arg1.toString().replace('.', ''));
  160. arg2 = Number(arg2.toString().replace('.', '')) * cm;
  161. } else {
  162. arg1 = Number(arg1.toString().replace('.', '')) * cm;
  163. arg2 = Number(arg2.toString().replace('.', ''));
  164. }
  165. } else {
  166. arg1 = Number(arg1.toString().replace('.', ''));
  167. arg2 = Number(arg2.toString().replace('.', ''));
  168. }
  169. return (arg1 + arg2) / m;
  170. },
  171. increase() {
  172. if (this.currentValue + this.step > this.max || this.disabled) return;
  173. this.currentValue = this.accAdd(this.step, this.currentValue);
  174. if (this.maxDisabled) {
  175. this.inputActive = false;
  176. }
  177. },
  178. decrease() {
  179. if (this.currentValue - this.step < this.min || this.disabled) return;
  180. this.currentValue = this.accSub(this.currentValue, this.step);
  181. if (this.minDisabled) {
  182. this.inputActive = false;
  183. }
  184. },
  185. activeInput(disabled) {
  186. if (!this.disabled && !disabled) {
  187. this.inputActive = true;
  188. }
  189. },
  190. inactiveInput(disabled) {
  191. if (!this.disabled && !disabled) {
  192. this.inputActive = false;
  193. }
  194. }
  195. }
  196. };
  197. </script>