[Improvement] Slider: add step & bar-height prop (#915)

This commit is contained in:
neverland
2018-04-23 20:19:41 +08:00
committed by GitHub
parent 19f4c9c028
commit b93a2e3c00
7 changed files with 160 additions and 350 deletions
+33 -102
View File
@@ -1,22 +1,8 @@
<template>
<div
class="van-slider"
:class="{ 'van-slider--disabled': disabled }"
>
<div
class="van-slider__bar"
ref="bar"
:style="barStyle"
@click.stop="onSliderClicked"
>
<div :class="b({ disabled })" @click.stop="onClick">
<div :class="b('bar')" :style="barStyle">
<span
class="van-slider__finished-portion"
:style="finishedStyle"
/>
<span
class="van-slider__pivot"
ref="pivot"
:style="pivotStyle"
:class="b('button')"
@touchstart="onTouchStart"
@touchmove.prevent.stop="onTouchMove"
@touchend="onTouchEnd"
@@ -25,145 +11,90 @@
</div>
</div>
</template>
<script>
<script>
import create from '../utils/create';
import Touch from '../mixins/touch';
const DEFAULT_COLOR = '#4b0';
const DEFAULT_BG = '#cacaca';
export default create({
name: 'slider',
mixins: [Touch],
props: {
disabled: Boolean,
max: {
type: Number,
default: 100
},
min: {
type: Number,
default: 0
},
step: {
type: Number,
default: 1
},
value: {
type: Number,
default: 0,
required: true
default: 0
},
disabled: Boolean,
pivotColor: {
barHeight: {
type: String,
default: DEFAULT_COLOR
},
barColor: {
type: String,
default: DEFAULT_BG
},
loadedBarColor: {
type: String,
default: DEFAULT_COLOR
default: '2px'
}
},
data() {
return {
pivotOffset: 0
};
},
computed: {
sliderWidth() {
const rect = this.$refs.bar.getBoundingClientRect();
return rect['width'];
},
barStyle() {
return {
backgroundColor: this.barColor
};
},
finishedStyle() {
return {
backgroundColor: this.loadedBarColor,
width: this.format(this.value) + '%'
};
},
pivotStyle() {
return {
backgroundColor: this.pivotColor,
left: this.format(this.value) + '%',
marginLeft: `-${this.pivotOffset}px`
width: this.format(this.value) + '%',
height: this.barHeight
};
}
},
mounted() {
this.pivotOffset = parseInt(this.$refs.pivot.getBoundingClientRect().width / 2);
},
methods: {
onTouchStart(event) {
if (this.disabled) return;
this.draging = true;
this.touchStart(event);
this.startValue = this.format(this.value);
},
onTouchMove(event) {
if (this.draging) {
this.touchMove(event);
const diff = this.deltaX / this.sliderWidth * 100;
this.newValue = this.startValue + diff;
this.updateValue(this.newValue);
}
if (this.disabled) return;
this.touchMove(event);
const rect = this.$el.getBoundingClientRect();
const diff = this.deltaX / rect.width * 100;
this.updateValue(this.startValue + diff);
},
onTouchEnd() {
if (this.draging) {
this.$nextTick(() => {
this.draging = false;
this.updateValue(this.newValue, true);
});
}
if (this.disabled) return;
this.updateValue(this.value, true);
},
onSliderClicked(e) {
if (this.disabled || this.draging) return;
const sliderRect = this.$refs.bar.getBoundingClientRect();
const sliderOffset = sliderRect.left;
this.newValue = Math.round((e.clientX - sliderOffset) / this.sliderWidth * 100);
this.updateValue(this.newValue, true);
},
updateValue(value, isFinished) {
onClick(event) {
if (this.disabled) return;
const rect = this.$el.getBoundingClientRect();
const value = (event.clientX - rect.left) / rect.width * 100;
this.updateValue(value, true);
},
updateValue(value, end) {
value = this.format(value);
this.$emit('change', value);
this.$emit('input', value);
if (isFinished) {
this.$emit('after-change', value);
if (end) {
this.$emit('change', value);
}
},
format(value) {
return Math.round(this.range(value));
},
range(value) {
return Math.max(this.min, Math.min(value, this.max));
return (Math.round(Math.max(this.min, Math.min(value, this.max)) / this.step) * this.step);
}
}
});
+16 -28
View File
@@ -1,41 +1,29 @@
@import './common/var.css';
$c-slider-background: #cacaca;
$c-pivot-border: #fff;
.van-slider {
&--disabled {
opacity: .3;
.van-slider__pivot {
cursor: not-allowed;
}
}
position: relative;
border-radius: 999px;
background-color: $border-color;
&__bar {
position: relative;
margin: 0 15px;
height: 4px;
border-radius: 5px;
background: $c-slider-background;
border-radius: inherit;
background-color: $blue;
}
&__loaded-portion,
&__finished-portion {
border-radius: 5px;
height: 100%;
position: absolute;
left: 0;
}
&__pivot {
&__button {
position: absolute;
top: 50%;
width: 16px;
height: 16px;
border: 3px solid $c-pivot-border;
box-shadow: 0 1px 4px;
right: 0;
width: 20px;
height: 20px;
border-radius: 50%;
background-color: $c-slider-background;
transform: translate3d(0, -50%, 0);
background-color: $white;
transform: translate3d(50%, -50%, 0);
box-shadow: 0 1px 2px rgba(0, 0, 0, .5);
}
&--disabled {
opacity: .3;
}
}