From 04d3d9b80d28a37222298000de5711671b5f1792 Mon Sep 17 00:00:00 2001 From: nemo-shen Date: Thu, 23 Sep 2021 17:33:27 +0800 Subject: [PATCH] feat(Slider): add vertical prop (#4486) * feat(Slider): add vertical prop * fix: adjust * Update README.md Co-authored-by: neverland Co-authored-by: neverland --- example/pages/slider/index.js | 8 +++--- example/pages/slider/index.wxml | 18 +++++++++++++ packages/slider/README.md | 48 +++++++++++++++++++++++++++++++++ packages/slider/index.less | 31 +++++++++++++++++++++ packages/slider/index.ts | 39 ++++++++++++++++++++++----- packages/slider/index.wxml | 4 +-- 6 files changed, 136 insertions(+), 12 deletions(-) diff --git a/example/pages/slider/index.js b/example/pages/slider/index.js index f4b849fd..673c7a08 100644 --- a/example/pages/slider/index.js +++ b/example/pages/slider/index.js @@ -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, }); - } + }, }); diff --git a/example/pages/slider/index.wxml b/example/pages/slider/index.wxml index 68f1c6eb..e9a2392f 100644 --- a/example/pages/slider/index.wxml +++ b/example/pages/slider/index.wxml @@ -63,3 +63,21 @@ + + + + + + + diff --git a/packages/slider/README.md b/packages/slider/README.md index a7a3d431..f3988c66 100644 --- a/packages/slider/README.md +++ b/packages/slider/README.md @@ -33,6 +33,25 @@ Page({ }); ``` +### 双滑块 + +添加 `range` 属性就可以开启双滑块模式,确保 `value` 的值是一个数组。 + +```html + +``` + +```js +Page({ + onChange(event) { + wx.showToast({ + icon: 'none', + title: `当前值:${event.detail}`, + }); + }, +}); +``` + ### 指定选择范围 ```html @@ -79,6 +98,34 @@ Page({ }); ``` +### 垂直方向 + +设置 `vertical` 属性后,滑块会垂直展示,且高度为 100% 父元素高度。 + +```html + + + + +``` + +```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 diff --git a/packages/slider/index.less b/packages/slider/index.less index 805f5ada..987a918f 100644 --- a/packages/slider/index.less +++ b/packages/slider/index.less @@ -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'); + } + } } diff --git a/packages/slider/index.ts b/packages/slider/index.ts index 1e0a02dd..33f9f904 100644 --- a/packages/slider/index.ts +++ b/packages/slider/index.ts @@ -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; diff --git a/packages/slider/index.wxml b/packages/slider/index.wxml index 7129a5bc..7c0184f7 100644 --- a/packages/slider/index.wxml +++ b/packages/slider/index.wxml @@ -2,8 +2,8 @@