| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314 | import { createNamespace, addUnit } from '../utils';import { deepClone } from '../utils/deep-clone';import { preventDefault } from '../utils/dom/event';import { range, addNumber } from '../utils/format/number';import { TouchMixin } from '../mixins/touch';import { FieldMixin } from '../mixins/field';var _createNamespace = createNamespace('slider'),    createComponent = _createNamespace[0],    bem = _createNamespace[1];var isSameValue = function isSameValue(newValue, oldValue) {  return JSON.stringify(newValue) === JSON.stringify(oldValue);};export default createComponent({  mixins: [TouchMixin, FieldMixin],  props: {    disabled: Boolean,    vertical: Boolean,    range: Boolean,    barHeight: [Number, String],    buttonSize: [Number, String],    activeColor: String,    inactiveColor: String,    min: {      type: [Number, String],      default: 0    },    max: {      type: [Number, String],      default: 100    },    step: {      type: [Number, String],      default: 1    },    value: {      type: [Number, Array],      default: 0    }  },  data: function data() {    return {      dragStatus: ''    };  },  computed: {    scope: function scope() {      return this.max - this.min;    },    buttonStyle: function buttonStyle() {      if (this.buttonSize) {        var size = addUnit(this.buttonSize);        return {          width: size,          height: size        };      }    }  },  created: function created() {    // format initial value    this.updateValue(this.value);  },  mounted: function mounted() {    if (this.range) {      this.bindTouchEvent(this.$refs.wrapper0);      this.bindTouchEvent(this.$refs.wrapper1);    } else {      this.bindTouchEvent(this.$refs.wrapper);    }  },  methods: {    onTouchStart: function onTouchStart(event) {      if (this.disabled) {        return;      }      this.touchStart(event);      this.currentValue = this.value;      if (this.range) {        this.startValue = this.value.map(this.format);      } else {        this.startValue = this.format(this.value);      }      this.dragStatus = 'start';    },    onTouchMove: function onTouchMove(event) {      if (this.disabled) {        return;      }      if (this.dragStatus === 'start') {        this.$emit('drag-start');      }      preventDefault(event, true);      this.touchMove(event);      this.dragStatus = 'draging';      var rect = this.$el.getBoundingClientRect();      var delta = this.vertical ? this.deltaY : this.deltaX;      var total = this.vertical ? rect.height : rect.width;      var diff = delta / total * this.scope;      if (this.range) {        this.currentValue[this.index] = this.startValue[this.index] + diff;      } else {        this.currentValue = this.startValue + diff;      }      this.updateValue(this.currentValue);    },    onTouchEnd: function onTouchEnd() {      if (this.disabled) {        return;      }      if (this.dragStatus === 'draging') {        this.updateValue(this.currentValue, true);        this.$emit('drag-end');      }      this.dragStatus = '';    },    onClick: function onClick(event) {      event.stopPropagation();      if (this.disabled) return;      var rect = this.$el.getBoundingClientRect();      var delta = this.vertical ? event.clientY - rect.top : event.clientX - rect.left;      var total = this.vertical ? rect.height : rect.width;      var value = +this.min + delta / total * this.scope;      if (this.range) {        var _this$value = this.value,            left = _this$value[0],            right = _this$value[1];        var middle = (left + right) / 2;        if (value <= middle) {          left = value;        } else {          right = value;        }        value = [left, right];      }      this.startValue = this.value;      this.updateValue(value, true);    },    // 处理两个滑块重叠之后的情况    handleOverlap: function handleOverlap(value) {      if (value[0] > value[1]) {        value = deepClone(value);        return value.reverse();      }      return value;    },    updateValue: function updateValue(value, end) {      if (this.range) {        value = this.handleOverlap(value).map(this.format);      } else {        value = this.format(value);      }      if (!isSameValue(value, this.value)) {        this.$emit('input', value);      }      if (end && !isSameValue(value, this.startValue)) {        this.$emit('change', value);      }    },    format: function format(value) {      var min = +this.min;      var max = +this.max;      var step = +this.step;      value = range(value, min, max);      var diff = Math.round((value - min) / step) * step;      return addNumber(min, diff);    }  },  render: function render() {    var _wrapperStyle,        _this = this,        _barStyle;    var h = arguments[0];    var vertical = this.vertical;    var mainAxis = vertical ? 'height' : 'width';    var crossAxis = vertical ? 'width' : 'height';    var wrapperStyle = (_wrapperStyle = {      background: this.inactiveColor    }, _wrapperStyle[crossAxis] = addUnit(this.barHeight), _wrapperStyle); // 计算选中条的长度百分比    var calcMainAxis = function calcMainAxis() {      var value = _this.value,          min = _this.min,          range = _this.range,          scope = _this.scope;      if (range) {        return (value[1] - value[0]) * 100 / scope + "%";      }      return (value - min) * 100 / scope + "%";    }; // 计算选中条的开始位置的偏移量    var calcOffset = function calcOffset() {      var value = _this.value,          min = _this.min,          range = _this.range,          scope = _this.scope;      if (range) {        return (value[0] - min) * 100 / scope + "%";      }      return null;    };    var barStyle = (_barStyle = {}, _barStyle[mainAxis] = calcMainAxis(), _barStyle.left = this.vertical ? null : calcOffset(), _barStyle.top = this.vertical ? calcOffset() : null, _barStyle.background = this.activeColor, _barStyle);    if (this.dragStatus) {      barStyle.transition = 'none';    }    var renderButton = function renderButton(i) {      var map = ['left', 'right'];      var isNumber = typeof i === 'number';      var current = isNumber ? _this.value[i] : _this.value;      var getClassName = function getClassName() {        if (isNumber) {          return "button-wrapper-" + map[i];        }        return "button-wrapper";      };      var getRefName = function getRefName() {        if (isNumber) {          return "wrapper" + i;        }        return "wrapper";      };      var renderButtonContent = function renderButtonContent() {        if (isNumber) {          var slot = _this.slots(i === 0 ? 'left-button' : 'right-button', {            value: current          });          if (slot) {            return slot;          }        }        if (_this.slots('button')) {          return _this.slots('button');        }        return h("div", {          "class": bem('button'),          "style": _this.buttonStyle        });      };      return h("div", {        "ref": getRefName(),        "attrs": {          "role": "slider",          "tabindex": _this.disabled ? -1 : 0,          "aria-valuemin": _this.min,          "aria-valuenow": _this.value,          "aria-valuemax": _this.max,          "aria-orientation": _this.vertical ? 'vertical' : 'horizontal'        },        "class": bem(getClassName()),        "on": {          "touchstart": function touchstart() {            if (isNumber) {              // 保存当前按钮的索引              _this.index = i;            }          },          "click": function click(e) {            return e.stopPropagation();          }        }      }, [renderButtonContent()]);    };    return h("div", {      "style": wrapperStyle,      "class": bem({        disabled: this.disabled,        vertical: vertical      }),      "on": {        "click": this.onClick      }    }, [h("div", {      "class": bem('bar'),      "style": barStyle    }, [this.range ? [renderButton(0), renderButton(1)] : renderButton()])]);  }});
 |