mirror of
https://gitee.com/vant-contrib/vant-weapp.git
synced 2025-04-06 03:58:05 +08:00
feat(Slider): add vertical prop (#4486)
* feat(Slider): add vertical prop * fix: adjust * Update README.md Co-authored-by: neverland <chenjiahan@youzan.com> Co-authored-by: neverland <chenjiahan@buaa.edu.cn>
This commit is contained in:
parent
1a7889590f
commit
04d3d9b80d
@ -2,19 +2,19 @@ import Page from '../../common/page';
|
||||
|
||||
Page({
|
||||
data: {
|
||||
currentValue: 50
|
||||
currentValue: 50,
|
||||
},
|
||||
|
||||
onChange(event) {
|
||||
wx.showToast({
|
||||
icon: 'none',
|
||||
title: `当前值:${event.detail}`
|
||||
title: `当前值:${event.detail}`,
|
||||
});
|
||||
},
|
||||
|
||||
onDrag(event) {
|
||||
this.setData({
|
||||
currentValue: event.detail.value
|
||||
currentValue: event.detail.value,
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -63,3 +63,21 @@
|
||||
</view>
|
||||
</van-slider>
|
||||
</demo-block>
|
||||
|
||||
<demo-block title="垂直方向">
|
||||
<view style="height: 150px; padding-left: 30px;">
|
||||
<van-slider
|
||||
value="{{ currentValue }}"
|
||||
vertical
|
||||
custom-class="slider"
|
||||
bind:change="onChange"
|
||||
/>
|
||||
<van-slider
|
||||
value="{{ [20, 60 ] }}"
|
||||
vertical
|
||||
range
|
||||
custom-class="slider"
|
||||
bind:change="onChange"
|
||||
/>
|
||||
</view>
|
||||
</demo-block>
|
||||
|
@ -33,6 +33,25 @@ Page({
|
||||
});
|
||||
```
|
||||
|
||||
### 双滑块
|
||||
|
||||
添加 `range` 属性就可以开启双滑块模式,确保 `value` 的值是一个数组。
|
||||
|
||||
```html
|
||||
<van-slider value="{{ 10, 50 }}" range @change="onChange" />
|
||||
```
|
||||
|
||||
```js
|
||||
Page({
|
||||
onChange(event) {
|
||||
wx.showToast({
|
||||
icon: 'none',
|
||||
title: `当前值:${event.detail}`,
|
||||
});
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### 指定选择范围
|
||||
|
||||
```html
|
||||
@ -79,6 +98,34 @@ Page({
|
||||
});
|
||||
```
|
||||
|
||||
### 垂直方向
|
||||
|
||||
设置 `vertical` 属性后,滑块会垂直展示,且高度为 100% 父元素高度。
|
||||
|
||||
```html
|
||||
<view style="height: 150px;">
|
||||
<van-slider value="50" vertical bind:change="onChange" />
|
||||
<van-slider
|
||||
value="{{ [10, 50] }}"
|
||||
range
|
||||
vertical
|
||||
style="margin-left: 100px;"
|
||||
bind:change="onChange"
|
||||
/>
|
||||
</view>
|
||||
```
|
||||
|
||||
```js
|
||||
Page({
|
||||
onChange(event) {
|
||||
wx.showToast({
|
||||
icon: 'none',
|
||||
title: `当前值:${event.detail}`,
|
||||
});
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### Props
|
||||
@ -95,6 +142,7 @@ Page({
|
||||
| inactive-color | 进度条默认颜色 | _string_ | `#e5e5e5` |
|
||||
| use-slot-button | 是否使用按钮插槽 | _boolean_ | `false` |
|
||||
| range `v1.8.4` | 是否开启双滑块模式 | _boolean_ | `false` |
|
||||
| vertical `v1.8.5` | 是否垂直展示 | _boolean_ | `false` |
|
||||
|
||||
### Events
|
||||
|
||||
|
@ -63,4 +63,35 @@
|
||||
&--disabled {
|
||||
opacity: var(--slider-disabled-opacity, @slider-disabled-opacity);
|
||||
}
|
||||
|
||||
&--vertical {
|
||||
display: inline-block;
|
||||
.theme(width, '@slider-bar-height');
|
||||
|
||||
height: 100%;
|
||||
|
||||
.van-slider__button-wrapper,
|
||||
.van-slider__button-wrapper-right {
|
||||
top: auto;
|
||||
right: 50%;
|
||||
bottom: 0;
|
||||
transform: translate3d(50%, 50%, 0);
|
||||
}
|
||||
|
||||
.van-slider__button-wrapper-left {
|
||||
top: 0;
|
||||
right: 50%;
|
||||
left: auto;
|
||||
transform: translate3d(50%, -50%, 0);
|
||||
}
|
||||
|
||||
// use pseudo element to expand click area
|
||||
&::before {
|
||||
top: 0;
|
||||
.theme(right, '-@padding-xs');
|
||||
|
||||
bottom: 0;
|
||||
.theme(left, '-@padding-xs');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { VantComponent } from '../common/component';
|
||||
import { touch } from '../mixins/touch';
|
||||
import { canIUseModel } from '../common/version';
|
||||
import { getRect } from '../common/utils';
|
||||
import { getRect, addUnit } from '../common/utils';
|
||||
|
||||
type SliderValue = number | [number, number];
|
||||
|
||||
@ -35,6 +35,7 @@ VantComponent({
|
||||
}
|
||||
},
|
||||
},
|
||||
vertical: Boolean,
|
||||
barHeight: null,
|
||||
},
|
||||
|
||||
@ -77,7 +78,10 @@ VantComponent({
|
||||
this.dragStatus = 'draging';
|
||||
|
||||
getRect(this, '.van-slider').then((rect) => {
|
||||
const diff = (this.deltaX / rect.width) * this.getRange();
|
||||
const { vertical } = this.data;
|
||||
const delta = vertical ? this.deltaY : this.deltaX;
|
||||
const total = vertical ? rect.height : rect.width;
|
||||
const diff = (delta / total) * this.getRange();
|
||||
|
||||
if (this.isRange(this.startValue)) {
|
||||
(this.newValue as [number, number])[this.buttonIndex] =
|
||||
@ -104,8 +108,12 @@ VantComponent({
|
||||
const { min } = this.data;
|
||||
|
||||
getRect(this, '.van-slider').then((rect) => {
|
||||
const value =
|
||||
((event.detail.x - rect.left) / rect.width) * this.getRange() + min;
|
||||
const { vertical } = this.data;
|
||||
const delta = vertical
|
||||
? event.detail.y - rect.top
|
||||
: event.detail.x - rect.left;
|
||||
const total = vertical ? rect.height : rect.width;
|
||||
const value = Number(min) + (delta / total) * this.getRange();
|
||||
|
||||
if (this.isRange(this.value)) {
|
||||
const [left, right] = this.value;
|
||||
@ -146,10 +154,18 @@ VantComponent({
|
||||
|
||||
this.value = value;
|
||||
|
||||
const { vertical } = this.data;
|
||||
const mainAxis = vertical ? 'height' : 'width';
|
||||
|
||||
this.setData({
|
||||
wrapperStyle: `
|
||||
background: ${this.data.inactiveColor || ''};
|
||||
${mainAxis}: ${addUnit(this.data.barHeight) || ''};
|
||||
`,
|
||||
barStyle: `
|
||||
width: ${this.calcMainAxis()};
|
||||
left: ${this.isRange(value) ? `${value[0]}%` : 0};
|
||||
${mainAxis}: ${this.calcMainAxis()};
|
||||
left: ${vertical ? 0 : this.calcOffset()};
|
||||
top: ${vertical ? this.calcOffset() : 0};
|
||||
${drag ? 'transition: none;' : ''}
|
||||
`,
|
||||
});
|
||||
@ -187,6 +203,17 @@ VantComponent({
|
||||
return `${((value - Number(min)) * 100) / scope}%`;
|
||||
},
|
||||
|
||||
// 计算选中条的开始位置的偏移量
|
||||
calcOffset() {
|
||||
const { value } = this;
|
||||
const { min } = this.data;
|
||||
const scope = this.getScope();
|
||||
if (this.isRange(value)) {
|
||||
return `${((value[0] - Number(min)) * 100) / scope}%`;
|
||||
}
|
||||
return '0%';
|
||||
},
|
||||
|
||||
format(value: number) {
|
||||
const { max, min, step } = this.data;
|
||||
return Math.round(Math.max(min, Math.min(value, max)) / step) * step;
|
||||
|
@ -2,8 +2,8 @@
|
||||
<wxs src="../wxs/style.wxs" module="style" />
|
||||
|
||||
<view
|
||||
class="custom-class {{ utils.bem('slider', { disabled }) }}"
|
||||
style="{{ style({ background: inactiveColor, height: utils.addUnit(barHeight) }) }}"
|
||||
class="custom-class {{ utils.bem('slider', { disabled, vertical }) }}"
|
||||
style="{{ wrapperStyle }}"
|
||||
bind:tap="onClick"
|
||||
>
|
||||
<view
|
||||
|
Loading…
x
Reference in New Issue
Block a user