Slider: add vertical mode

pull/4375/head
devange 2017-04-11 13:44:54 +08:00 committed by 杨奕
parent 46650289b7
commit 8e1d8329aa
5 changed files with 189 additions and 17 deletions

View File

@ -10,7 +10,8 @@
value6: 0,
value7: 0,
value8: 0,
value9: [4, 8]
value9: [4, 8],
value10: 0
};
},
methods: {
@ -171,6 +172,34 @@ Selecting a range of values is supported.
```
:::
### Vertical mode
Vertical slider
:::demo Setting the `vertical` attribute to switch to the vertical mode, the `size` attribute must be setted as the heigth of slider
```html
<template>
<div class="block">
<el-slider
v-model="value10"
vertical
size="300px">
</el-slider>
</div>
</template>
<script>
export default {
data() {
return {
value10: 0
}
}
}
</script>
```
:::
## Attributes
| Attribute | Description | Type | Accepted Values | Default |
|---------- |-------------- |---------- |-------------------------------- |-------- |
@ -184,6 +213,8 @@ Selecting a range of values is supported.
| show-tooltip | whether to display tooltip value | boolean | — | true |
| format-tooltip | format to display tooltip value | Function(value) | — | — |
| range | whether to select a range | boolean | — | false |
| vertical | vertical mode | boolean | — | false |
| size | width or height, it should be setted when vertical mode | String | — | - |
## Events
| Event Name | Description | Parameters |

View File

@ -10,7 +10,8 @@
value6: 0,
value7: 0,
value8: 0,
value9: [4, 8]
value9: [4, 8],
value10: 0
};
},
methods: {
@ -195,6 +196,34 @@
```
:::
### 竖向模式
竖向滑块
:::demo 设置`vertical`可使滑块变成竖向模式,必须设置滑块高度`size`属性
```html
<template>
<div class="block">
<el-slider
v-model="value10"
vertical
size="300px">
</el-slider>
</div>
</template>
<script>
export default {
data() {
return {
value10: 0
}
}
}
</script>
```
:::
### Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------------- |---------- |-------------------------------- |-------- |
@ -208,6 +237,8 @@
| show-tooltip | 是否显示 tooltip | boolean | — | true |
| format-tooltip | 格式化 tooltip message | Function(value) | — | — |
| range | 是否为范围选择 | boolean | — | false |
| vertical | 是否竖向模式 | boolean | — | false |
| size | 宽度或高度,竖向模式时务必设置 | String | — | - |
### Events
| 事件名称 | 说明 | 回调参数 |

View File

@ -5,7 +5,7 @@
@mouseleave="handleMouseLeave"
@mousedown="onButtonDown"
:class="{ 'hover': hovering, 'dragging': dragging }"
:style="{ left: currentPosition }"
:style="this.vertical ? { bottom: currentPosition } : { left: currentPosition }"
ref="button">
<el-tooltip placement="top" ref="tooltip" :disabled="!showTooltip">
<span slot="content">{{ formatValue }}</span>
@ -28,6 +28,10 @@
value: {
type: Number,
default: 0
},
vertical: {
type: Boolean,
default: false
}
},
@ -37,6 +41,8 @@
dragging: false,
startX: 0,
currentX: 0,
startY: 0,
currentY: 0,
startPosition: 0,
newPosition: null,
oldValue: this.value
@ -117,15 +123,25 @@
onDragStart(event) {
this.dragging = true;
this.startX = event.clientX;
if (this.vertical) {
this.startY = event.clientY;
} else {
this.startX = event.clientX;
}
this.startPosition = parseFloat(this.currentPosition);
},
onDragging(event) {
if (this.dragging) {
this.displayTooltip();
this.currentX = event.clientX;
const diff = (this.currentX - this.startX) / this.$parent.$sliderWidth * 100;
let diff = 0;
if (this.vertical) {
this.currentY = event.clientY;
diff = (this.startY - this.currentY) / this.$parent.$sliderSize * 100;
} else {
this.currentX = event.clientX;
diff = (this.currentX - this.startX) / this.$parent.$sliderSize * 100;
}
this.newPosition = this.startPosition + diff;
this.setPosition(this.newPosition);
}

View File

@ -1,5 +1,6 @@
<template>
<div class="el-slider">
<div class="el-slider"
:class="{ 'el-slider__vertical': vertical, 'el-slider__with_input': showInput }">
<el-input-number
v-model="firstValue"
v-if="showInput && !range"
@ -14,20 +15,26 @@
</el-input-number>
<div class="el-slider__runway"
:class="{ 'show-input': showInput, 'disabled': disabled }"
:style="vertical ? size && { height: size } : size && { width: size }"
@click="onSliderClick"
ref="slider">
<div
class="el-slider__bar"
:style="{
width: barWidth,
left: barLeft
:style="vertical ? {
height: barSize,
bottom: barStart
} : {
width: barSize,
left: barStart
}">
</div>
<slider-button
:vertical="vertical"
v-model="firstValue"
ref="button1">
</slider-button>
<slider-button
:vertical="vertical"
v-model="secondValue"
ref="button2"
v-if="range">
@ -35,7 +42,7 @@
<div
class="el-slider__stop"
v-for="item in stops"
:style="{ 'left': item + '%' }"
:style="vertical ? { 'bottom': item + '%' } : { 'left': item + '%' }"
v-if="showStops">
</div>
</div>
@ -94,6 +101,13 @@
range: {
type: Boolean,
default: false
},
vertical: {
type: Boolean,
default: false
},
size: {
type: String
}
},
@ -213,14 +227,19 @@
onSliderClick(event) {
if (this.disabled || this.dragging) return;
const sliderOffsetLeft = this.$refs.slider.getBoundingClientRect().left;
this.setPosition((event.clientX - sliderOffsetLeft) / this.$sliderWidth * 100);
if (this.vertical) {
const sliderOffsetBottom = this.$refs.slider.getBoundingClientRect().bottom;
this.setPosition((event.clientY - sliderOffsetBottom) / this.$sliderSize * 100);
} else {
const sliderOffsetLeft = this.$refs.slider.getBoundingClientRect().left;
this.setPosition((event.clientX - sliderOffsetLeft) / this.$sliderSize * 100);
}
}
},
computed: {
$sliderWidth() {
return parseInt(getStyle(this.$refs.slider, 'width'), 10);
$sliderSize() {
return parseInt(getStyle(this.$refs.slider, (this.vertical ? 'height' : 'width')), 10);
},
stops() {
@ -248,13 +267,13 @@
return Math.max(this.firstValue, this.secondValue);
},
barWidth() {
barSize() {
return this.range
? `${ 100 * (this.maxValue - this.minValue) / (this.max - this.min) }%`
: `${ 100 * (this.firstValue - this.min) / (this.max - this.min) }%`;
},
barLeft() {
barStart() {
return this.range
? `${ 100 * (this.minValue - this.min) / (this.max - this.min) }%`
: '0%';

View File

@ -128,5 +128,80 @@
background-color: var(--slider-stop-background-color);
transform: translateX(-50%);
}
@e vertical {
position: relative;
.el-slider__runway {
width: 4px;
height: 100%;
margin: 0 16px;
}
.el-slider__bar {
width: 4px;
height: auto;
border-radius: 0 0 3px 3px;
}
.el-slider__button-wrapper {
top: auto;
left: var(--slider-button-wrapper-offset);
transform: translateY(50%);
}
.el-slider__stop {
transform: translateY(50%);
}
&.el-slider__with_input {
padding-bottom: var(--input-large-height);
.el-slider__input {
overflow: visible;
float: none;
position: absolute;
bottom: 0;
width: 36px;
margin-top: 15px;
.el-input__inner {
text-align: center;
padding-left: 5px;
padding-right: 5px;
}
.el-input-number__decrease,
.el-input-number__increase
{
top: var(--input-small-height);
margin-top: -1px;
border: var(--input-border);
line-height: 20px;
box-sizing: border-box;
transition: var(--border-transition-base);
}
.el-input-number__decrease {
width: 18px;
right: 18px;
border-bottom-left-radius: var(--input-border-radius);
}
.el-input-number__increase {
width: 19px;
border-bottom-right-radius: var(--input-border-radius);
& ~ .el-input .el-input__inner {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
}
&:hover {
.el-input-number__decrease,
.el-input-number__increase
{
border-color: var(--input-hover-border);
}
}
&:active {
.el-input-number__decrease,
.el-input-number__increase
{
border-color: var(--input-focus-border);
}
}
}
}
}
}
}