diff --git a/example/pages/dashboard/config.js b/example/pages/dashboard/config.js
index 5687cade..e8b00068 100644
--- a/example/pages/dashboard/config.js
+++ b/example/pages/dashboard/config.js
@@ -75,7 +75,7 @@ export default {
name: 'Select 选择',
path: '/pages/select/index'
}, {
- name: 'Stepper 计数器',
+ name: 'Stepper 步进器',
path: '/pages/stepper/index'
}, {
name: 'Switch 开关',
diff --git a/example/pages/stepper/index.js b/example/pages/stepper/index.js
index b6eb0d6f..560d44d4 100644
--- a/example/pages/stepper/index.js
+++ b/example/pages/stepper/index.js
@@ -1,32 +1 @@
-Page(Object.assign({}, {
- data: {
- stepper1: {
- stepper: 10,
- min: 1
- },
- stepper2: {
- stepper: 10,
- min: 1,
- max: 20
- },
- stepper3: {
- stepper: 10,
- min: 1,
- max: 20,
- step: 2
- }
- },
-
- handleZanStepperChange({
- detail: stepper,
- target: {
- dataset: {
- componentId
- }
- }
- }) {
- this.setData({
- [`${componentId}.stepper`]: stepper
- });
- }
-}));
+Page({});
diff --git a/example/pages/stepper/index.json b/example/pages/stepper/index.json
index f53d6938..838e47f0 100644
--- a/example/pages/stepper/index.json
+++ b/example/pages/stepper/index.json
@@ -1,6 +1,7 @@
{
- "navigationBarTitleText": "Stepper 计数器",
+ "navigationBarTitleText": "Stepper 步进器",
"usingComponents": {
+ "demo-block": "../../components/demo-block/index",
"van-stepper": "../../dist/stepper/index",
"van-panel": "../../dist/panel/index"
}
diff --git a/example/pages/stepper/index.wxml b/example/pages/stepper/index.wxml
index 2f4e1396..127db1aa 100644
--- a/example/pages/stepper/index.wxml
+++ b/example/pages/stepper/index.wxml
@@ -1,60 +1,17 @@
-
-
-
-
-
-
+
+
+
-
-
-
- small:
-
+
+
- >
-
- middle:
-
-
- large:
-
-
-
-
-
-
-
-
-
-
+
+
+
diff --git a/packages/stepper/README.md b/packages/stepper/README.md
index f0cbb3db..3729f1ed 100644
--- a/packages/stepper/README.md
+++ b/packages/stepper/README.md
@@ -1,73 +1,72 @@
-## Stepper 计数器
+## Stepper 步进器
### 使用指南
+
在 index.json 中引入组件
```json
-{
- "usingComponents": {
- "van-stepper": "path/to/vant-weapp/dist/stepper/index"
- }
+"usingComponents": {
+ "van-stepper": "path/to/vant-weapp/dist/stepper/index"
}
```
### 代码演示
#### 基础用法
-`Stepper` 组件通过传入的 stepper 对象控制,内部数据格式如下:
-```js
-Page({
- data: {
- stepper: {
- // 当前 stepper 数字
- stepper: 1,
- // 最小可到的数字
- min: 1,
- // 最大可到的数字
- max: 1,
- // 尺寸
- size: 'small'
- }
- },
- handleZanStepperChange({
- // stepper 代表操作后,应该要展示的数字,需要设置到数据对象里,才会更新页面展示
- detail: stepper
- }) {
- this.setData({
- 'stepper.stepper': stepper
- });
- }
-});
+```html
+
```
-当一个 `Stepper` 中,min 超过 max,就会导致组件被置灰。
+#### 禁用状态
-当 stepper 被点击时,需要监听`change`事件,处理计数器值的改变。
+通过设置`disabled`属性来禁用 stepper
-```js
+```html
+
+```
+
+#### 高级用法
+
+默认是每次加减为1,可以对组件设置`step`、`min`、`max`属性
+
+```html
-
+ value="{{ value }}"
+ integer
+ min="5"
+ max="40"
+ step="2"
+ bind:change="onChange"
+/>
```
### API
-| 参数 | 说明 | 类型 | 默认值 | 必须 |
-|-----------|-----------|-----------|-------------|-------------|
-| size | 计数器尺寸:small、middle、large | String | middle | |
-| stepper | 计数器的值 | Number | `1` | 必须 |
-| min | 计数器最小值 | Number | `1` | |
-| max | 计数器最大值 | Number | 无穷大 | |
-| step | 步数 | Number | `1` | |
+| 参数 | 说明 | 类型 | 默认值 |
+|-----------|-----------|-----------|-------------|
+| value | 输入值 | `String | Number` | 最小值 |
+| min | 最小值 | `String | Number` | `1` |
+| max | 最大值 | `String | Number` | - |
+| step | 步数 | `String | Number` | `1` |
+| integer | 是否只允许输入整数 | `Boolean` | `false` |
+| disabled | 是否禁用 | `Boolean` | `false` |
+| disable-input | 是否禁用input框 | `Boolean` | `false` |
### Event
-| 事件名称 | 说明 | 回调参数 |
+| 事件名称 | 说明 | 回调参数 |
|-----------|-----------|-----------|
-| change | 当绑定值变化时触发的事件 | `{ index, stepper }` |
-| minus | 点击减少按钮时触发 | - |
+| change | 当绑定值变化时触发的事件 | event.detail: 当前输入的值 |
+| overlimit | 点击不可用的按钮时触发 | - |
| plus | 点击增加按钮时触发 | - |
+| minus | 点击减少按钮时触发 | - |
+| blur | 输入框失焦时触发 | - |
+
+### 外部样式类
+
+| 类名 | 说明 |
+|-----------|-----------|
+| custom-class | 根节点样式类 |
+| input-class | 输入框样式类 |
+| plus-class | 加号按钮样式类 |
+| minus-class | 减号按钮样式类 |
diff --git a/packages/stepper/index.js b/packages/stepper/index.js
index ba1c55b2..cacdb9d8 100644
--- a/packages/stepper/index.js
+++ b/packages/stepper/index.js
@@ -1,79 +1,88 @@
// Note that the bitwise operators and shift operators operate on 32-bit ints
// so in that case, the max safe integer is 2^31-1, or 2147483647
-const VERY_LARGE_NUMBER = 2147483647;
+const MAX = 2147483647;
Component({
+ externalClasses: [
+ 'custom-class',
+ 'input-class',
+ 'plus-class',
+ 'minus-class'
+ ],
+
properties: {
- size: {
- type: String,
- value: 'middle'
- },
- stepper: {
- type: Number,
- value: 1
+ value: {
+ type: null,
+ observer(val) {
+ if (val !== this.currentValue) {
+ this.setData({ currentValue: this.range(val) });
+ }
+ }
},
+ integer: Boolean,
+ disabled: Boolean,
+ disableInput: Boolean,
min: {
- type: Number,
+ type: null,
value: 1
},
max: {
- type: Number,
- value: VERY_LARGE_NUMBER
+ type: null,
+ value: MAX
},
step: {
- type: Number,
+ type: null,
value: 1
}
},
+ attached() {
+ this.setData({
+ currentValue: this.range(this.data.value)
+ });
+ },
+
methods: {
- handleZanStepperChange(e, type) {
- const { dataset = {} } = e.currentTarget;
- const { disabled } = dataset;
- const { step } = this.data;
- let { stepper } = this.data;
-
- if (disabled) return null;
-
- if (type === 'minus') {
- stepper -= step;
- } else if (type === 'plus') {
- stepper += step;
- }
-
- if (stepper < this.data.min || stepper > this.data.max) return null;
-
- this.triggerEvent('change', stepper);
- this.triggerEvent(type);
+ // limit value range
+ range(value) {
+ return Math.max(Math.min(this.data.max, value), this.data.min);
},
- handleZanStepperMinus(e) {
- this.handleZanStepperChange(e, 'minus');
+ onInput(event) {
+ const { value = '' } = event.detail || {};
+ this.triggerInput(value);
},
- handleZanStepperPlus(e) {
- this.handleZanStepperChange(e, 'plus');
- },
-
- handleZanStepperBlur(e) {
- let { value } = e.detail;
- const { min, max } = this.data;
-
- if (!value) {
- setTimeout(() => {
- this.triggerEvent('change', min);
- }, 16);
+ onChange(type) {
+ if (this[`${type}Disabled`]) {
+ this.triggerEvent('overlimit', type);
return;
}
- value = +value;
- if (value > max) {
- value = max;
- } else if (value < min) {
- value = min;
- }
+ const diff = type === 'minus' ? -this.data.step : +this.data.step;
+ const value = Math.round((this.data.currentValue + diff) * 100) / 100;
+ this.triggerInput(this.range(value));
+ this.triggerEvent(type);
+ },
- this.triggerEvent('change', value);
+ onBlur(event) {
+ const currentValue = this.range(this.data.currentValue);
+ this.triggerInput(currentValue);
+ this.triggerEvent('blur', event);
+ },
+
+ onMinus() {
+ this.onChange('minus');
+ },
+
+ onPlus() {
+ this.onChange('plus');
+ },
+
+ triggerInput(currentValue) {
+ this.setData({ currentValue });
+ this.triggerEvent('input', currentValue);
+ this.triggerEvent('change', currentValue);
}
}
});
diff --git a/packages/stepper/index.pcss b/packages/stepper/index.pcss
index 8a6d59a8..1b1e5dc6 100644
--- a/packages/stepper/index.pcss
+++ b/packages/stepper/index.pcss
@@ -1,63 +1,93 @@
+@import '../helper/index.pcss';
+
.van-stepper {
- color: #666;
-}
-.van-stepper view {
- display: inline-block;
- padding: 5px 0;
- text-align: center;
- box-sizing: border-box;
- vertical-align: middle;
- font-size: 12px;
- border: 1rpx solid #999;
-}
-.van-stepper .van-stepper__minus {
- border-right: none;
- border-radius: 2px 0 0 2px;
-}
-.van-stepper .van-stepper__text {
- border: 1rpx solid #999;
- display: inline-block;
- text-align: center;
- vertical-align: middle;
- /* 重置 input 默认样式 */
- min-height: auto;
- font-size: 12px;
-}
-.van-stepper .van-stepper__plus {
- border-left: none;
- border-radius: 0 2px 2px 0;
-}
-.van-stepper .van-stepper--disabled {
- background: #f8f8f8;
- color: #bbb;
- border-color: #e8e8e8;
-}
-.van-stepper--small view {
- min-width: 36px;
- line-height: 18px;
-}
-.van-stepper--small .van-stepper__text {
- width: 36px;
- line-height: 28px;
- height: 28px;
-}
+ font-size: 0;
-.van-stepper--middle view {
- min-width: 40px;
- line-height: 20px;
-}
-.van-stepper--middle .van-stepper__text {
- width: 40px;
- line-height: 30px;
- height: 30px;
-}
+ &__minus,
+ &__plus,
+ &__input {
+ display: inline-block;
+ vertical-align: middle;
+ background-color: $white;
+ }
-.van-stepper--large view {
- min-width: 44px;
- line-height: 22px;
-}
-.van-stepper--large .van-stepper__text {
- width: 44px;
- line-height: 32px;
- height: 32px;
+ &__minus,
+ &__plus {
+ width: 40px;
+ height: 30px;
+ box-sizing: border-box;
+ border: 1px solid $border-color;
+ position: relative;
+ padding: 5px;
+
+ &::before {
+ width: 9px;
+ height: 1px;
+ }
+
+ &::after {
+ width: 1px;
+ height: 9px;
+ }
+
+ &::before,
+ &::after {
+ content: '';
+ position: absolute;
+ margin: auto;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: #6c6c6c;
+ }
+
+ &:active {
+ background-color: $active-color;
+ }
+
+ &--disabled {
+ background-color: $background-color;
+
+ &::before,
+ &::after {
+ background-color: $gray;
+ }
+ }
+
+ &--disabled:active {
+ background-color: $background-color;
+ }
+ }
+
+ &__minus {
+ border-radius: 2px 0 0 2px;
+
+ &::after {
+ display: none;
+ }
+ }
+
+ &__plus {
+ border-radius: 0 2px 2px 0;
+ }
+
+ &__input {
+ width: 33px;
+ height: 26px;
+ padding: 1px;
+ border: 1px solid $border-color;
+ border-width: 1px 0;
+ border-radius: 0;
+ box-sizing: content-box;
+ color: $gray-darker;
+ font-size: 14px;
+ text-align: center;
+ -webkit-appearance: none;
+
+ &--disabled {
+ color: $gray;
+ background-color: $background-color;
+ }
+ }
}
diff --git a/packages/stepper/index.wxml b/packages/stepper/index.wxml
index 11c4680a..478d25e9 100644
--- a/packages/stepper/index.wxml
+++ b/packages/stepper/index.wxml
@@ -1,23 +1,18 @@
-
+
- -
-
+ class="minus-class van-stepper__minus {{ disabled || currentValue <= min ? 'van-stepper__minus--disabled' : '' }}"
+ bind:tap="onMinus"
+ />
- +
-
+ class="plus-class van-stepper__plus {{ disabled || currentValue >= max ? 'van-stepper__plus--disabled' : '' }}"
+ bind:tap="onPlus"
+ />