index.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. import { use, isDef } from '../utils';
  2. var _use = use('stepper'),
  3. sfc = _use[0],
  4. bem = _use[1];
  5. export default sfc({
  6. props: {
  7. value: null,
  8. integer: Boolean,
  9. disabled: Boolean,
  10. inputWidth: String,
  11. asyncChange: Boolean,
  12. disableInput: Boolean,
  13. min: {
  14. type: [String, Number],
  15. "default": 1
  16. },
  17. max: {
  18. type: [String, Number],
  19. "default": Infinity
  20. },
  21. step: {
  22. type: [String, Number],
  23. "default": 1
  24. },
  25. defaultValue: {
  26. type: [String, Number],
  27. "default": 1
  28. }
  29. },
  30. data: function data() {
  31. var value = this.range(isDef(this.value) ? this.value : this.defaultValue);
  32. if (value !== +this.value) {
  33. this.$emit('input', value);
  34. }
  35. return {
  36. currentValue: value
  37. };
  38. },
  39. computed: {
  40. minusDisabled: function minusDisabled() {
  41. return this.disabled || this.currentValue <= this.min;
  42. },
  43. plusDisabled: function plusDisabled() {
  44. return this.disabled || this.currentValue >= this.max;
  45. }
  46. },
  47. watch: {
  48. value: function value(val) {
  49. if (val !== this.currentValue) {
  50. this.currentValue = this.format(val);
  51. }
  52. },
  53. currentValue: function currentValue(val) {
  54. this.$emit('input', val);
  55. this.$emit('change', val);
  56. }
  57. },
  58. methods: {
  59. // filter illegal characters
  60. format: function format(value) {
  61. value = String(value).replace(/[^0-9.-]/g, '');
  62. return value === '' ? 0 : this.integer ? Math.floor(value) : +value;
  63. },
  64. // limit value range
  65. range: function range(value) {
  66. return Math.max(Math.min(this.max, this.format(value)), this.min);
  67. },
  68. onInput: function onInput(event) {
  69. var value = event.target.value;
  70. var formatted = this.format(value);
  71. if (!this.asyncChange) {
  72. if (+value !== formatted) {
  73. event.target.value = formatted;
  74. }
  75. this.currentValue = formatted;
  76. } else {
  77. event.target.value = this.currentValue;
  78. this.$emit('input', formatted);
  79. this.$emit('change', formatted);
  80. }
  81. },
  82. onChange: function onChange(type) {
  83. if (this[type + "Disabled"]) {
  84. this.$emit('overlimit', type);
  85. return;
  86. }
  87. var diff = type === 'minus' ? -this.step : +this.step;
  88. var value = Math.round((this.currentValue + diff) * 100) / 100;
  89. if (!this.asyncChange) {
  90. this.currentValue = this.range(value);
  91. } else {
  92. this.$emit('input', value);
  93. this.$emit('change', value);
  94. }
  95. this.$emit(type);
  96. },
  97. onFocus: function onFocus(event) {
  98. this.$emit('focus', event);
  99. },
  100. onBlur: function onBlur(event) {
  101. this.currentValue = this.range(this.currentValue);
  102. this.$emit('blur', event); // fix edge case when input is empty and min is 0
  103. if (this.currentValue === 0) {
  104. event.target.value = this.currentValue;
  105. }
  106. }
  107. },
  108. render: function render(h) {
  109. var _this = this;
  110. var onChange = function onChange(type) {
  111. return function () {
  112. _this.onChange(type);
  113. };
  114. };
  115. return h("div", {
  116. "class": bem()
  117. }, [h("button", {
  118. "class": bem('minus', {
  119. disabled: this.minusDisabled
  120. }),
  121. "on": {
  122. "click": onChange('minus')
  123. }
  124. }), h("input", {
  125. "attrs": {
  126. "type": "number",
  127. "disabled": this.disabled || this.disableInput
  128. },
  129. "class": bem('input'),
  130. "domProps": {
  131. "value": this.currentValue
  132. },
  133. "style": {
  134. width: this.inputWidth
  135. },
  136. "on": {
  137. "input": this.onInput,
  138. "focus": this.onFocus,
  139. "blur": this.onBlur
  140. }
  141. }), h("button", {
  142. "class": bem('plus', {
  143. disabled: this.plusDisabled
  144. }),
  145. "on": {
  146. "click": onChange('plus')
  147. }
  148. })]);
  149. }
  150. });