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({
|
Page({
|
||||||
data: {
|
data: {
|
||||||
currentValue: 50
|
currentValue: 50,
|
||||||
},
|
},
|
||||||
|
|
||||||
onChange(event) {
|
onChange(event) {
|
||||||
wx.showToast({
|
wx.showToast({
|
||||||
icon: 'none',
|
icon: 'none',
|
||||||
title: `当前值:${event.detail}`
|
title: `当前值:${event.detail}`,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onDrag(event) {
|
onDrag(event) {
|
||||||
this.setData({
|
this.setData({
|
||||||
currentValue: event.detail.value
|
currentValue: event.detail.value,
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
@ -63,3 +63,21 @@
|
|||||||
</view>
|
</view>
|
||||||
</van-slider>
|
</van-slider>
|
||||||
</demo-block>
|
</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
|
```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
|
## API
|
||||||
|
|
||||||
### Props
|
### Props
|
||||||
@ -95,6 +142,7 @@ Page({
|
|||||||
| inactive-color | 进度条默认颜色 | _string_ | `#e5e5e5` |
|
| inactive-color | 进度条默认颜色 | _string_ | `#e5e5e5` |
|
||||||
| use-slot-button | 是否使用按钮插槽 | _boolean_ | `false` |
|
| use-slot-button | 是否使用按钮插槽 | _boolean_ | `false` |
|
||||||
| range `v1.8.4` | 是否开启双滑块模式 | _boolean_ | `false` |
|
| range `v1.8.4` | 是否开启双滑块模式 | _boolean_ | `false` |
|
||||||
|
| vertical `v1.8.5` | 是否垂直展示 | _boolean_ | `false` |
|
||||||
|
|
||||||
### Events
|
### Events
|
||||||
|
|
||||||
|
@ -63,4 +63,35 @@
|
|||||||
&--disabled {
|
&--disabled {
|
||||||
opacity: var(--slider-disabled-opacity, @slider-disabled-opacity);
|
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 { VantComponent } from '../common/component';
|
||||||
import { touch } from '../mixins/touch';
|
import { touch } from '../mixins/touch';
|
||||||
import { canIUseModel } from '../common/version';
|
import { canIUseModel } from '../common/version';
|
||||||
import { getRect } from '../common/utils';
|
import { getRect, addUnit } from '../common/utils';
|
||||||
|
|
||||||
type SliderValue = number | [number, number];
|
type SliderValue = number | [number, number];
|
||||||
|
|
||||||
@ -35,6 +35,7 @@ VantComponent({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
vertical: Boolean,
|
||||||
barHeight: null,
|
barHeight: null,
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -77,7 +78,10 @@ VantComponent({
|
|||||||
this.dragStatus = 'draging';
|
this.dragStatus = 'draging';
|
||||||
|
|
||||||
getRect(this, '.van-slider').then((rect) => {
|
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)) {
|
if (this.isRange(this.startValue)) {
|
||||||
(this.newValue as [number, number])[this.buttonIndex] =
|
(this.newValue as [number, number])[this.buttonIndex] =
|
||||||
@ -104,8 +108,12 @@ VantComponent({
|
|||||||
const { min } = this.data;
|
const { min } = this.data;
|
||||||
|
|
||||||
getRect(this, '.van-slider').then((rect) => {
|
getRect(this, '.van-slider').then((rect) => {
|
||||||
const value =
|
const { vertical } = this.data;
|
||||||
((event.detail.x - rect.left) / rect.width) * this.getRange() + min;
|
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)) {
|
if (this.isRange(this.value)) {
|
||||||
const [left, right] = this.value;
|
const [left, right] = this.value;
|
||||||
@ -146,10 +154,18 @@ VantComponent({
|
|||||||
|
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
|
||||||
|
const { vertical } = this.data;
|
||||||
|
const mainAxis = vertical ? 'height' : 'width';
|
||||||
|
|
||||||
this.setData({
|
this.setData({
|
||||||
|
wrapperStyle: `
|
||||||
|
background: ${this.data.inactiveColor || ''};
|
||||||
|
${mainAxis}: ${addUnit(this.data.barHeight) || ''};
|
||||||
|
`,
|
||||||
barStyle: `
|
barStyle: `
|
||||||
width: ${this.calcMainAxis()};
|
${mainAxis}: ${this.calcMainAxis()};
|
||||||
left: ${this.isRange(value) ? `${value[0]}%` : 0};
|
left: ${vertical ? 0 : this.calcOffset()};
|
||||||
|
top: ${vertical ? this.calcOffset() : 0};
|
||||||
${drag ? 'transition: none;' : ''}
|
${drag ? 'transition: none;' : ''}
|
||||||
`,
|
`,
|
||||||
});
|
});
|
||||||
@ -187,6 +203,17 @@ VantComponent({
|
|||||||
return `${((value - Number(min)) * 100) / scope}%`;
|
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) {
|
format(value: number) {
|
||||||
const { max, min, step } = this.data;
|
const { max, min, step } = this.data;
|
||||||
return Math.round(Math.max(min, Math.min(value, max)) / step) * step;
|
return Math.round(Math.max(min, Math.min(value, max)) / step) * step;
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
<wxs src="../wxs/style.wxs" module="style" />
|
<wxs src="../wxs/style.wxs" module="style" />
|
||||||
|
|
||||||
<view
|
<view
|
||||||
class="custom-class {{ utils.bem('slider', { disabled }) }}"
|
class="custom-class {{ utils.bem('slider', { disabled, vertical }) }}"
|
||||||
style="{{ style({ background: inactiveColor, height: utils.addUnit(barHeight) }) }}"
|
style="{{ wrapperStyle }}"
|
||||||
bind:tap="onClick"
|
bind:tap="onClick"
|
||||||
>
|
>
|
||||||
<view
|
<view
|
||||||
|
Loading…
x
Reference in New Issue
Block a user