index.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. <template>
  2. <uni-shadow-root class="weapp-lib-slider-index"><view :class="'custom-class '+(utils.bem('slider', { disabled, vertical }))" :style="wrapperStyle" @click="onClick">
  3. <view :class="utils.bem('slider__bar')" :style="(barStyle)+'; '+(style({ backgroundColor: activeColor }))">
  4. <view v-if="range" :class="utils.bem('slider__button-wrapper-left')" :data-index="0" @touchstart="onTouchStart" @touchmove.stop.prevent="onTouchMove" @touchend="onTouchEnd" @touchcancel="onTouchEnd">
  5. <slot v-if="useButtonSlot" name="left-button"></slot>
  6. <view v-else :class="utils.bem('slider__button')"></view>
  7. </view>
  8. <view v-if="range" :class="utils.bem('slider__button-wrapper-right')" :data-index="1" @touchstart="onTouchStart" @touchmove.stop.prevent="onTouchMove" @touchend="onTouchEnd" @touchcancel="onTouchEnd">
  9. <slot v-if="useButtonSlot" name="right-button"></slot>
  10. <view v-else :class="utils.bem('slider__button')"></view>
  11. </view>
  12. <view v-if="(!range)" :class="utils.bem('slider__button-wrapper')" @touchstart="onTouchStart" @touchmove.stop.prevent="onTouchMove" @touchend="onTouchEnd" @touchcancel="onTouchEnd">
  13. <slot v-if="useButtonSlot" name="button"></slot>
  14. <view v-else :class="utils.bem('slider__button')"></view>
  15. </view>
  16. </view>
  17. </view></uni-shadow-root>
  18. </template>
  19. <wxs src="../wxs/utils.wxs" module="utils"></wxs><wxs src="../wxs/style.wxs" module="style"></wxs>
  20. <script>
  21. global['__wxRoute'] = 'weapp/lib/slider/index'
  22. "use strict";
  23. Object.defineProperty(exports, "__esModule", { value: true });
  24. var component_1 = require("../common/component");
  25. var touch_1 = require("../mixins/touch");
  26. var version_1 = require("../common/version");
  27. var utils_1 = require("../common/utils");
  28. var DRAG_STATUS = {
  29. START: 'start',
  30. MOVING: 'moving',
  31. END: 'end',
  32. };
  33. (0, component_1.VantComponent)({
  34. mixins: [touch_1.touch],
  35. props: {
  36. range: Boolean,
  37. disabled: Boolean,
  38. useButtonSlot: Boolean,
  39. activeColor: String,
  40. inactiveColor: String,
  41. max: {
  42. type: Number,
  43. value: 100,
  44. },
  45. min: {
  46. type: Number,
  47. value: 0,
  48. },
  49. step: {
  50. type: Number,
  51. value: 1,
  52. },
  53. value: {
  54. type: null,
  55. value: 0,
  56. observer: function (val) {
  57. if (val !== this.value) {
  58. this.updateValue(val);
  59. }
  60. },
  61. },
  62. vertical: Boolean,
  63. barHeight: null,
  64. },
  65. created: function () {
  66. this.updateValue(this.data.value);
  67. },
  68. methods: {
  69. onTouchStart: function (event) {
  70. var _this = this;
  71. if (this.data.disabled)
  72. return;
  73. var index = event.currentTarget.dataset.index;
  74. if (typeof index === 'number') {
  75. this.buttonIndex = index;
  76. }
  77. this.touchStart(event);
  78. this.startValue = this.format(this.value);
  79. this.newValue = this.value;
  80. if (this.isRange(this.newValue)) {
  81. this.startValue = this.newValue.map(function (val) { return _this.format(val); });
  82. }
  83. else {
  84. this.startValue = this.format(this.newValue);
  85. }
  86. this.dragStatus = DRAG_STATUS.START;
  87. },
  88. onTouchMove: function (event) {
  89. var _this = this;
  90. if (this.data.disabled)
  91. return;
  92. if (this.dragStatus === DRAG_STATUS.START) {
  93. this.$emit('drag-start');
  94. }
  95. this.touchMove(event);
  96. this.dragStatus = DRAG_STATUS.MOVING;
  97. (0, utils_1.getRect)(this, '.van-slider').then(function (rect) {
  98. var vertical = _this.data.vertical;
  99. var delta = vertical ? _this.deltaY : _this.deltaX;
  100. var total = vertical ? rect.height : rect.width;
  101. var diff = (delta / total) * _this.getRange();
  102. if (_this.isRange(_this.startValue)) {
  103. _this.newValue[_this.buttonIndex] =
  104. _this.startValue[_this.buttonIndex] + diff;
  105. }
  106. else {
  107. _this.newValue = _this.startValue + diff;
  108. }
  109. _this.updateValue(_this.newValue, false, true);
  110. });
  111. },
  112. onTouchEnd: function () {
  113. var _this = this;
  114. if (this.data.disabled)
  115. return;
  116. if (this.dragStatus === DRAG_STATUS.MOVING) {
  117. this.dragStatus = DRAG_STATUS.END;
  118. (0, utils_1.nextTick)(function () {
  119. _this.updateValue(_this.newValue, true);
  120. _this.$emit('drag-end');
  121. });
  122. }
  123. },
  124. onClick: function (event) {
  125. var _this = this;
  126. if (this.data.disabled)
  127. return;
  128. var min = this.data.min;
  129. (0, utils_1.getRect)(this, '.van-slider').then(function (rect) {
  130. var vertical = _this.data.vertical;
  131. var touch = event.touches[0];
  132. var delta = vertical
  133. ? touch.clientY - rect.top
  134. : touch.clientX - rect.left;
  135. var total = vertical ? rect.height : rect.width;
  136. var value = Number(min) + (delta / total) * _this.getRange();
  137. if (_this.isRange(_this.value)) {
  138. var _a = _this.value, left = _a[0], right = _a[1];
  139. var middle = (left + right) / 2;
  140. if (value <= middle) {
  141. _this.updateValue([value, right], true);
  142. }
  143. else {
  144. _this.updateValue([left, value], true);
  145. }
  146. }
  147. else {
  148. _this.updateValue(value, true);
  149. }
  150. });
  151. },
  152. isRange: function (val) {
  153. var range = this.data.range;
  154. return range && Array.isArray(val);
  155. },
  156. handleOverlap: function (value) {
  157. if (value[0] > value[1]) {
  158. return value.slice(0).reverse();
  159. }
  160. return value;
  161. },
  162. updateValue: function (value, end, drag) {
  163. var _this = this;
  164. if (this.isRange(value)) {
  165. value = this.handleOverlap(value).map(function (val) { return _this.format(val); });
  166. }
  167. else {
  168. value = this.format(value);
  169. }
  170. this.value = value;
  171. var vertical = this.data.vertical;
  172. var mainAxis = vertical ? 'height' : 'width';
  173. this.setData({
  174. wrapperStyle: "\n background: ".concat(this.data.inactiveColor || '', ";\n ").concat(vertical ? 'width' : 'height', ": ").concat((0, utils_1.addUnit)(this.data.barHeight) || '', ";\n "),
  175. barStyle: "\n ".concat(mainAxis, ": ").concat(this.calcMainAxis(), ";\n left: ").concat(vertical ? 0 : this.calcOffset(), ";\n top: ").concat(vertical ? this.calcOffset() : 0, ";\n ").concat(drag ? 'transition: none;' : '', "\n "),
  176. });
  177. if (drag) {
  178. this.$emit('drag', { value: value });
  179. }
  180. if (end) {
  181. this.$emit('change', value);
  182. }
  183. if ((drag || end) && (0, version_1.canIUseModel)()) {
  184. this.setData({ value: value });
  185. }
  186. },
  187. getScope: function () {
  188. return Number(this.data.max) - Number(this.data.min);
  189. },
  190. getRange: function () {
  191. var _a = this.data, max = _a.max, min = _a.min;
  192. return max - min;
  193. },
  194. getOffsetWidth: function (current, min) {
  195. var scope = this.getScope();
  196. // 避免最小值小于最小step时出现负数情况
  197. return "".concat(Math.max(((current - min) * 100) / scope, 0), "%");
  198. },
  199. // 计算选中条的长度百分比
  200. calcMainAxis: function () {
  201. var value = this.value;
  202. var min = this.data.min;
  203. if (this.isRange(value)) {
  204. return this.getOffsetWidth(value[1], value[0]);
  205. }
  206. return this.getOffsetWidth(value, Number(min));
  207. },
  208. // 计算选中条的开始位置的偏移量
  209. calcOffset: function () {
  210. var value = this.value;
  211. var min = this.data.min;
  212. var scope = this.getScope();
  213. if (this.isRange(value)) {
  214. return "".concat(((value[0] - Number(min)) * 100) / scope, "%");
  215. }
  216. return '0%';
  217. },
  218. format: function (value) {
  219. var _a = this.data, max = _a.max, min = _a.min, step = _a.step;
  220. return Math.round(Math.max(min, Math.min(value, max)) / step) * step;
  221. },
  222. },
  223. });
  224. export default global['__wxComponents']['weapp/lib/slider/index']
  225. </script>
  226. <style platform="mp-weixin">
  227. @import '../common/index.css';.van-slider{background-color:var(--slider-inactive-background-color,#ebedf0);border-radius:999px;height:var(--slider-bar-height,2px);position:relative}.van-slider:before{bottom:calc(var(--padding-xs, 8px)*-1);content:"";left:0;position:absolute;right:0;top:calc(var(--padding-xs, 8px)*-1)}.van-slider__bar{background-color:var(--slider-active-background-color,#1989fa);border-radius:inherit;height:100%;position:relative;transition:all .2s;width:100%}.van-slider__button{background-color:var(--slider-button-background-color,#fff);border-radius:var(--slider-button-border-radius,50%);box-shadow:var(--slider-button-box-shadow,0 1px 2px rgba(0,0,0,.5));height:var(--slider-button-height,24px);width:var(--slider-button-width,24px)}.van-slider__button-wrapper,.van-slider__button-wrapper-right{position:absolute;right:0;top:50%;transform:translate3d(50%,-50%,0)}.van-slider__button-wrapper-left{left:0;position:absolute;top:50%;transform:translate3d(-50%,-50%,0)}.van-slider--disabled{opacity:var(--slider-disabled-opacity,.5)}.van-slider--vertical{display:inline-block;height:100%;width:var(--slider-bar-height,2px)}.van-slider--vertical .van-slider__button-wrapper,.van-slider--vertical .van-slider__button-wrapper-right{bottom:0;right:50%;top:auto;transform:translate3d(50%,50%,0)}.van-slider--vertical .van-slider__button-wrapper-left{left:auto;right:50%;top:0;transform:translate3d(50%,-50%,0)}.van-slider--vertical:before{bottom:0;left:-8px;right:-8px;top:0}
  228. </style>