mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
[new feature] Slider: add vertical prop (#3078)
This commit is contained in:
parent
ee5e49bda0
commit
7e9ca167fa
@ -53,6 +53,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</van-slider>
|
</van-slider>
|
||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
|
<demo-block :title="$t('vertical')">
|
||||||
|
<div :style="{ height: '120px', paddingLeft: '30px' }">
|
||||||
|
<van-slider
|
||||||
|
v-model="value7"
|
||||||
|
vertical
|
||||||
|
@change="onChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</demo-block>
|
||||||
</demo-section>
|
</demo-section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -66,7 +76,8 @@ export default {
|
|||||||
title4: '指定步长',
|
title4: '指定步长',
|
||||||
customStyle: '自定义样式',
|
customStyle: '自定义样式',
|
||||||
customButton: '自定义按钮',
|
customButton: '自定义按钮',
|
||||||
text: '当前值:'
|
text: '当前值:',
|
||||||
|
vertical: '垂直方向'
|
||||||
},
|
},
|
||||||
'en-US': {
|
'en-US': {
|
||||||
title1: 'Basic Usage',
|
title1: 'Basic Usage',
|
||||||
@ -75,7 +86,8 @@ export default {
|
|||||||
title4: 'Step size',
|
title4: 'Step size',
|
||||||
customStyle: 'Custom Style',
|
customStyle: 'Custom Style',
|
||||||
customButton: 'Custom Button',
|
customButton: 'Custom Button',
|
||||||
text: 'Current value: '
|
text: 'Current value: ',
|
||||||
|
vertical: 'Vertical'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -86,7 +98,8 @@ export default {
|
|||||||
value3: 50,
|
value3: 50,
|
||||||
value4: 50,
|
value4: 50,
|
||||||
value5: 50,
|
value5: 50,
|
||||||
value6: 50
|
value6: 50,
|
||||||
|
value7: 50
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -74,6 +74,14 @@ export default {
|
|||||||
</van-slider>
|
</van-slider>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Vertical
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div :style="{ height: '100px' }">
|
||||||
|
<van-slider v-model="value" vertical />
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
### API
|
### API
|
||||||
|
|
||||||
| Attribute | Description | Type | Default |
|
| Attribute | Description | Type | Default |
|
||||||
@ -86,6 +94,7 @@ export default {
|
|||||||
| bar-height | Height of bar | `String` | `2px` |
|
| bar-height | Height of bar | `String` | `2px` |
|
||||||
| active-color | Active color of bar | `String` | `#1989fa` |
|
| active-color | Active color of bar | `String` | `#1989fa` |
|
||||||
| inactive-color | Inactive color of bar | `String` | `#e5e5e5` |
|
| inactive-color | Inactive color of bar | `String` | `#e5e5e5` |
|
||||||
|
| vertical | Whether to display vertical | `Boolean` | `false` |
|
||||||
|
|
||||||
### Event
|
### Event
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ export default sfc({
|
|||||||
min: Number,
|
min: Number,
|
||||||
value: Number,
|
value: Number,
|
||||||
disabled: Boolean,
|
disabled: Boolean,
|
||||||
|
vertical: Boolean,
|
||||||
activeColor: String,
|
activeColor: String,
|
||||||
inactiveColor: String,
|
inactiveColor: String,
|
||||||
max: {
|
max: {
|
||||||
@ -41,8 +42,12 @@ export default sfc({
|
|||||||
if (this.disabled) return;
|
if (this.disabled) return;
|
||||||
|
|
||||||
this.touchMove(event);
|
this.touchMove(event);
|
||||||
|
|
||||||
const rect = this.$el.getBoundingClientRect();
|
const rect = this.$el.getBoundingClientRect();
|
||||||
const diff = (this.deltaX / rect.width) * 100;
|
const delta = this.vertical ? this.deltaY : this.deltaX;
|
||||||
|
const total = this.vertical ? rect.height : rect.width;
|
||||||
|
const diff = (delta / total) * 100;
|
||||||
|
|
||||||
this.updateValue(this.startValue + diff);
|
this.updateValue(this.startValue + diff);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -57,7 +62,10 @@ export default sfc({
|
|||||||
if (this.disabled) return;
|
if (this.disabled) return;
|
||||||
|
|
||||||
const rect = this.$el.getBoundingClientRect();
|
const rect = this.$el.getBoundingClientRect();
|
||||||
const value = ((event.clientX - rect.left) / rect.width) * 100;
|
const delta = this.vertical ? event.clientY - rect.top : event.clientX - rect.left;
|
||||||
|
const total = this.vertical ? rect.height : rect.width;
|
||||||
|
const value = (delta / total) * 100;
|
||||||
|
|
||||||
this.updateValue(value, true);
|
this.updateValue(value, true);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -71,23 +79,33 @@ export default sfc({
|
|||||||
},
|
},
|
||||||
|
|
||||||
format(value) {
|
format(value) {
|
||||||
return Math.round(Math.max(this.min, Math.min(value, this.max)) / this.step) * this.step;
|
return (
|
||||||
|
Math.round(Math.max(this.min, Math.min(value, this.max)) / this.step) * this.step
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
render(h) {
|
render(h) {
|
||||||
|
const { vertical } = this;
|
||||||
const style = {
|
const style = {
|
||||||
background: this.inactiveColor
|
background: this.inactiveColor
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const mainAxis = vertical ? 'height' : 'width';
|
||||||
|
const crossAxis = vertical ? 'width' : 'height';
|
||||||
|
|
||||||
const barStyle = {
|
const barStyle = {
|
||||||
width: `${this.format(this.value)}%`,
|
[mainAxis]: `${this.format(this.value)}%`,
|
||||||
height: this.barHeight,
|
[crossAxis]: this.barHeight,
|
||||||
background: this.activeColor
|
background: this.activeColor
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={style} class={bem({ disabled: this.disabled })} onClick={this.onClick}>
|
<div
|
||||||
|
style={style}
|
||||||
|
class={bem({ disabled: this.disabled, vertical })}
|
||||||
|
onClick={this.onClick}
|
||||||
|
>
|
||||||
<div class={bem('bar')} style={barStyle}>
|
<div class={bem('bar')} style={barStyle}>
|
||||||
<div
|
<div
|
||||||
class={bem('button-wrapper')}
|
class={bem('button-wrapper')}
|
||||||
|
@ -39,4 +39,15 @@
|
|||||||
&--disabled {
|
&--disabled {
|
||||||
opacity: .3;
|
opacity: .3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&--vertical {
|
||||||
|
height: 100%;
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
.van-slider__button-wrapper {
|
||||||
|
top: auto;
|
||||||
|
bottom: 0;
|
||||||
|
transform: translate3d(50%, 50%, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,5 +58,16 @@ exports[`renders demo correctly 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<div style="height:120px;padding-left:30px;">
|
||||||
|
<div class="van-slider van-slider--vertical">
|
||||||
|
<div class="van-slider__bar" style="height:50%;width:2px;">
|
||||||
|
<div class="van-slider__button-wrapper">
|
||||||
|
<div class="van-slider__button"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
@ -20,6 +20,16 @@ exports[`click bar 2`] = `
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`click vertical 1`] = `
|
||||||
|
<div class="van-slider van-slider--vertical">
|
||||||
|
<div class="van-slider__bar" style="height: 100%; width: 2px;">
|
||||||
|
<div class="van-slider__button-wrapper">
|
||||||
|
<div class="van-slider__button"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`drag button 1`] = `
|
exports[`drag button 1`] = `
|
||||||
<div class="van-slider van-slider--disabled">
|
<div class="van-slider van-slider--disabled">
|
||||||
<div class="van-slider__bar" style="width: 50%; height: 2px;">
|
<div class="van-slider__bar" style="width: 50%; height: 2px;">
|
||||||
@ -39,3 +49,13 @@ exports[`drag button 2`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`drag button vertical 1`] = `
|
||||||
|
<div class="van-slider van-slider--vertical">
|
||||||
|
<div class="van-slider__bar" style="height: 100%; width: 2px;">
|
||||||
|
<div class="van-slider__button-wrapper">
|
||||||
|
<div class="van-slider__button"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
@ -1,11 +1,19 @@
|
|||||||
import Slider from '..';
|
import Slider from '..';
|
||||||
import { mount, triggerDrag, trigger } from '../../../test/utils';
|
import { mount, triggerDrag, trigger } from '../../../test/utils';
|
||||||
|
|
||||||
Element.prototype.getBoundingClientRect = jest.fn(() => ({ width: 100, left: 0 }));
|
function mockGetBoundingClientRect(vertical) {
|
||||||
|
Element.prototype.getBoundingClientRect = jest.fn(() => ({
|
||||||
|
width: vertical ? 0 : 100,
|
||||||
|
height: vertical ? 100 : 0,
|
||||||
|
top: vertical ? 0 : 100,
|
||||||
|
left: vertical ? 100 : 0
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
test('drag button', () => {
|
test('drag button', () => {
|
||||||
|
mockGetBoundingClientRect();
|
||||||
|
|
||||||
const wrapper = mount(Slider, {
|
const wrapper = mount(Slider, {
|
||||||
attachToDocument: true,
|
|
||||||
propsData: {
|
propsData: {
|
||||||
value: 50,
|
value: 50,
|
||||||
disabled: true
|
disabled: true
|
||||||
@ -26,6 +34,8 @@ test('drag button', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('click bar', () => {
|
it('click bar', () => {
|
||||||
|
mockGetBoundingClientRect();
|
||||||
|
|
||||||
const wrapper = mount(Slider, {
|
const wrapper = mount(Slider, {
|
||||||
propsData: {
|
propsData: {
|
||||||
value: 50,
|
value: 50,
|
||||||
@ -44,3 +54,40 @@ it('click bar', () => {
|
|||||||
trigger(wrapper, 'click', 100, 0);
|
trigger(wrapper, 'click', 100, 0);
|
||||||
expect(wrapper).toMatchSnapshot();
|
expect(wrapper).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('drag button vertical', () => {
|
||||||
|
mockGetBoundingClientRect(true);
|
||||||
|
|
||||||
|
const wrapper = mount(Slider, {
|
||||||
|
propsData: {
|
||||||
|
value: 50,
|
||||||
|
vertical: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
wrapper.vm.$on('input', value => {
|
||||||
|
wrapper.setProps({ value });
|
||||||
|
});
|
||||||
|
|
||||||
|
const button = wrapper.find('.van-slider__button');
|
||||||
|
triggerDrag(button, 0, 50);
|
||||||
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('click vertical', () => {
|
||||||
|
mockGetBoundingClientRect(true);
|
||||||
|
|
||||||
|
const wrapper = mount(Slider, {
|
||||||
|
propsData: {
|
||||||
|
value: 50,
|
||||||
|
vertical: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
wrapper.vm.$on('input', value => {
|
||||||
|
wrapper.setProps({ value });
|
||||||
|
});
|
||||||
|
|
||||||
|
trigger(wrapper, 'click', 0, 100);
|
||||||
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
@ -73,6 +73,16 @@ export default {
|
|||||||
</van-slider>
|
</van-slider>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### 垂直方向
|
||||||
|
|
||||||
|
Slider 垂直展示时,高度为 100% 父元素高度
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div :style="{ height: '100px' }">
|
||||||
|
<van-slider v-model="value" vertical />
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
### API
|
### API
|
||||||
|
|
||||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||||
@ -85,6 +95,7 @@ export default {
|
|||||||
| bar-height | 进度条高度 | `String` | `2px` | 1.1.0 |
|
| bar-height | 进度条高度 | `String` | `2px` | 1.1.0 |
|
||||||
| active-color | 进度条激活态颜色 | `String` | `#1989fa` | 1.5.1 |
|
| active-color | 进度条激活态颜色 | `String` | `#1989fa` | 1.5.1 |
|
||||||
| inactive-color | 进度条默认颜色 | `String` | `#e5e5e5` | 1.5.1 |
|
| inactive-color | 进度条默认颜色 | `String` | `#e5e5e5` | 1.5.1 |
|
||||||
|
| vertical | 是否垂直展示 | `Boolean` | `false` | 1.6.13 |
|
||||||
|
|
||||||
### Event
|
### Event
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user