index.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. import { use } from '../utils';
  2. import { TouchMixin } from '../mixins/touch';
  3. import { preventDefault } from '../utils/event';
  4. const [sfc, bem] = use('slider');
  5. export default sfc({
  6. mixins: [TouchMixin],
  7. props: {
  8. min: Number,
  9. value: Number,
  10. disabled: Boolean,
  11. vertical: Boolean,
  12. activeColor: String,
  13. inactiveColor: String,
  14. max: {
  15. type: Number,
  16. default: 100
  17. },
  18. step: {
  19. type: Number,
  20. default: 1
  21. },
  22. barHeight: {
  23. type: String,
  24. default: '2px'
  25. }
  26. },
  27. methods: {
  28. onTouchStart(event) {
  29. if (this.disabled) return;
  30. this.touchStart(event);
  31. this.startValue = this.format(this.value);
  32. },
  33. onTouchMove(event) {
  34. preventDefault(event, true);
  35. if (this.disabled) return;
  36. this.touchMove(event);
  37. const rect = this.$el.getBoundingClientRect();
  38. const delta = this.vertical ? this.deltaY : this.deltaX;
  39. const total = this.vertical ? rect.height : rect.width;
  40. const diff = (delta / total) * 100;
  41. this.newValue = this.startValue + diff;
  42. this.updateValue(this.newValue);
  43. },
  44. onTouchEnd() {
  45. if (this.disabled) return;
  46. this.updateValue(this.newValue, true);
  47. },
  48. onClick(event) {
  49. event.stopPropagation();
  50. if (this.disabled) return;
  51. const rect = this.$el.getBoundingClientRect();
  52. const delta = this.vertical ? event.clientY - rect.top : event.clientX - rect.left;
  53. const total = this.vertical ? rect.height : rect.width;
  54. const value = (delta / total) * 100;
  55. this.updateValue(value, true);
  56. },
  57. updateValue(value, end) {
  58. value = this.format(value);
  59. this.$emit('input', value);
  60. if (end) {
  61. this.$emit('change', value);
  62. }
  63. },
  64. format(value) {
  65. return (
  66. Math.round(Math.max(this.min, Math.min(value, this.max)) / this.step) * this.step
  67. );
  68. }
  69. },
  70. render(h) {
  71. const { vertical } = this;
  72. const style = {
  73. background: this.inactiveColor
  74. };
  75. const mainAxis = vertical ? 'height' : 'width';
  76. const crossAxis = vertical ? 'width' : 'height';
  77. const barStyle = {
  78. [mainAxis]: `${this.format(this.value)}%`,
  79. [crossAxis]: this.barHeight,
  80. background: this.activeColor
  81. };
  82. return (
  83. <div
  84. style={style}
  85. class={bem({ disabled: this.disabled, vertical })}
  86. onClick={this.onClick}
  87. >
  88. <div class={bem('bar')} style={barStyle}>
  89. <div
  90. class={bem('button-wrapper')}
  91. onTouchstart={this.onTouchStart}
  92. onTouchmove={this.onTouchMove}
  93. onTouchend={this.onTouchEnd}
  94. onTouchcancel={this.onTouchEnd}
  95. >
  96. {this.slots('button') || <div class={bem('button')} />}
  97. </div>
  98. </div>
  99. </div>
  100. );
  101. }
  102. });