mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
breaking change(Stepper): rename async-change to before-change
This commit is contained in:
parent
c277603160
commit
e026d2d83f
@ -201,6 +201,10 @@ Vue 3.0 中增加了 `Teleport` 组件,提供将组件渲染到任意 DOM 位
|
||||
|
||||
- `trigger` 属性的默认值调整为 `click`
|
||||
|
||||
#### Stepper
|
||||
|
||||
- `async-change` 属性重命名为 `before-change`,并调整使用方法
|
||||
|
||||
#### SwipeCell
|
||||
|
||||
- `open` 事件的 `detail` 参数重命名为 `name`
|
||||
|
@ -71,10 +71,10 @@ export default {
|
||||
<van-stepper v-model="value" input-width="40px" button-size="32px" />
|
||||
```
|
||||
|
||||
### Async Change
|
||||
### Before Change
|
||||
|
||||
```html
|
||||
<van-stepper :model-value="value" async-change @change="onChange" />
|
||||
<van-stepper v-model="value" :before-change="beforeChange" />
|
||||
```
|
||||
|
||||
```js
|
||||
@ -85,22 +85,22 @@ export default {
|
||||
setup() {
|
||||
const value = ref(1);
|
||||
|
||||
let timer;
|
||||
const onChange = (newValue) => {
|
||||
if (newValue === value.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
const beforeChange = (value) => {
|
||||
Toast.loading({ forbidClick: true });
|
||||
|
||||
clearTimeout(this.timer);
|
||||
timer = setTimeout(() => {
|
||||
Toast.clear();
|
||||
value.value = newValue;
|
||||
}, 500);
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
Toast.clear();
|
||||
// resolve 'true' or 'false'
|
||||
resolve(true);
|
||||
}, 500);
|
||||
});
|
||||
};
|
||||
|
||||
return { value };
|
||||
return {
|
||||
value,
|
||||
beforeChange,
|
||||
};
|
||||
},
|
||||
};
|
||||
```
|
||||
@ -116,7 +116,7 @@ export default {
|
||||
### Props
|
||||
|
||||
| Attribute | Description | Type | Default |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| --- | --- | --- | --- |
|
||||
| v-model | Current value | _number \| string_ | - |
|
||||
| min | Min value | _number \| string_ | `1` |
|
||||
| max | Max value | _number \| string_ | - |
|
||||
@ -133,7 +133,7 @@ export default {
|
||||
| disable-plus | Whether to disable plus button | _boolean_ | `false` |
|
||||
| disable-minus | Whether to disable minus button | _boolean_ | `false` |
|
||||
| disable-input | Whether to disable input | _boolean_ | `false` |
|
||||
| async-change | Whether to enable async change | _boolean_ | `false` | - |
|
||||
| before-change | Callback function before changing,return `false` to prevent change,support return Promise | _(value) => boolean \| Promise_ | `false` |
|
||||
| show-plus | Whether to show plus button | _boolean_ | `true` |
|
||||
| show-minus | Whether to show minus button | _boolean_ | `true` |
|
||||
| long-press `v2.4.3` | Whether to allow long press | _boolean_ | `true` |
|
||||
|
@ -93,10 +93,10 @@ export default {
|
||||
|
||||
### 异步变更
|
||||
|
||||
如果需要异步地修改输入框的值,可以设置 `async-change` 属性,并在 `change` 事件中手动修改 `value`。
|
||||
通过 `before-change` 属性可以在
|
||||
|
||||
```html
|
||||
<van-stepper :model-value="value" async-change @change="onChange" />
|
||||
<van-stepper v-model="value" :before-change="beforeChange" />
|
||||
```
|
||||
|
||||
```js
|
||||
@ -107,22 +107,22 @@ export default {
|
||||
setup() {
|
||||
const value = ref(1);
|
||||
|
||||
let timer;
|
||||
const onChange = (newValue) => {
|
||||
if (newValue === value.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
const beforeChange = (value) => {
|
||||
Toast.loading({ forbidClick: true });
|
||||
|
||||
clearTimeout(this.timer);
|
||||
timer = setTimeout(() => {
|
||||
Toast.clear();
|
||||
value.value = newValue;
|
||||
}, 500);
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
Toast.clear();
|
||||
// 在 resolve 函数中返回 true 或 false
|
||||
resolve(true);
|
||||
}, 500);
|
||||
});
|
||||
};
|
||||
|
||||
return { value };
|
||||
return {
|
||||
value,
|
||||
beforeChange,
|
||||
};
|
||||
},
|
||||
};
|
||||
```
|
||||
@ -157,7 +157,7 @@ export default {
|
||||
| disable-plus | 是否禁用增加按钮 | _boolean_ | `false` |
|
||||
| disable-minus | 是否禁用减少按钮 | _boolean_ | `false` |
|
||||
| disable-input | 是否禁用输入框 | _boolean_ | `false` |
|
||||
| async-change | 是否开启异步变更,开启后需要手动控制输入值 | _boolean_ | `false` |
|
||||
| before-change | 输入值变化前的回调函数,返回 `false` 可阻止输入,支持返回 Promise | _(value) => boolean \| Promise_ | `false` |
|
||||
| show-plus | 是否显示增加按钮 | _boolean_ | `true` |
|
||||
| show-minus | 是否显示减少按钮 | _boolean_ | `true` |
|
||||
| long-press `v2.4.3` | 是否开启长按手势 | _boolean_ | `true` |
|
||||
|
@ -31,8 +31,8 @@
|
||||
<van-stepper v-model="stepper7" button-size="32px" input-width="40px" />
|
||||
</van-cell>
|
||||
|
||||
<van-cell center :title="t('asyncChange')">
|
||||
<van-stepper :model-value="stepper6" async-change @change="onChange" />
|
||||
<van-cell center :title="t('beforeChange')">
|
||||
<van-stepper v-model="stepper6" :before-change="beforeChange" />
|
||||
</van-cell>
|
||||
|
||||
<van-cell v-if="!isWeapp" center :title="t('roundTheme')">
|
||||
@ -56,8 +56,8 @@ export default {
|
||||
range: '限制输入范围',
|
||||
integer: '限制输入整数',
|
||||
roundTheme: '圆角风格',
|
||||
asyncChange: '异步变更',
|
||||
customSize: '自定义大小',
|
||||
beforeChange: '异步变更',
|
||||
disableInput: '禁用输入框',
|
||||
decimalLength: '固定小数位数',
|
||||
},
|
||||
@ -66,8 +66,8 @@ export default {
|
||||
range: 'Range',
|
||||
integer: 'Integer',
|
||||
roundTheme: 'Round Theme',
|
||||
asyncChange: 'Async Change',
|
||||
customSize: 'Custom Size',
|
||||
beforeChange: 'Before Change',
|
||||
disableInput: 'Disable Input',
|
||||
decimalLength: 'Decimal Length',
|
||||
},
|
||||
@ -87,24 +87,20 @@ export default {
|
||||
disabledInput: 1,
|
||||
});
|
||||
|
||||
let timer;
|
||||
const onChange = (newValue) => {
|
||||
if (newValue === state.stepper6) {
|
||||
return;
|
||||
}
|
||||
|
||||
const beforeChange = () => {
|
||||
Toast.loading({ forbidClick: true });
|
||||
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(() => {
|
||||
state.stepper6 = newValue;
|
||||
Toast.clear();
|
||||
}, 500);
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
Toast.clear();
|
||||
resolve(true);
|
||||
}, 500);
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
...toRefs(state),
|
||||
onChange,
|
||||
beforeChange,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { ref, watch, computed } from 'vue';
|
||||
import { ref, watch, computed, PropType } from 'vue';
|
||||
|
||||
// Utils
|
||||
import { isNaN } from '../utils/validate/number';
|
||||
@ -14,6 +14,7 @@ import {
|
||||
|
||||
// Composition
|
||||
import { useLinkField } from '../composables/use-link-field';
|
||||
import { Interceptor, callInterceptor } from '../utils/interceptor';
|
||||
|
||||
const [createComponent, bem] = createNamespace('stepper');
|
||||
|
||||
@ -39,11 +40,11 @@ export default createComponent({
|
||||
modelValue: [Number, String],
|
||||
inputWidth: [Number, String],
|
||||
buttonSize: [Number, String],
|
||||
asyncChange: Boolean,
|
||||
placeholder: String,
|
||||
disablePlus: Boolean,
|
||||
disableMinus: Boolean,
|
||||
disableInput: Boolean,
|
||||
beforeChange: Function as PropType<Interceptor>,
|
||||
decimalLength: [Number, String],
|
||||
name: {
|
||||
type: [Number, String],
|
||||
@ -147,10 +148,15 @@ export default createComponent({
|
||||
}
|
||||
};
|
||||
|
||||
const emitChange = (value: string | number) => {
|
||||
if (props.asyncChange) {
|
||||
emit('update:modelValue', value);
|
||||
emit('change', value, { name: props.name });
|
||||
const setValue = (value: string | number) => {
|
||||
if (props.beforeChange) {
|
||||
callInterceptor({
|
||||
args: [value],
|
||||
interceptor: props.beforeChange,
|
||||
done() {
|
||||
current.value = value;
|
||||
},
|
||||
});
|
||||
} else {
|
||||
current.value = value;
|
||||
}
|
||||
@ -168,7 +174,7 @@ export default createComponent({
|
||||
const diff = actionType === 'minus' ? -props.step : +props.step;
|
||||
const value = format(add(+current.value, diff));
|
||||
|
||||
emitChange(value);
|
||||
setValue(value);
|
||||
emit(actionType);
|
||||
};
|
||||
|
||||
@ -185,11 +191,13 @@ export default createComponent({
|
||||
formatted = `${pair[0]}.${pair[1].slice(0, +decimalLength)}`;
|
||||
}
|
||||
|
||||
if (!equal(value, formatted)) {
|
||||
if (props.beforeChange) {
|
||||
input.value = String(current.value);
|
||||
} else if (!equal(value, formatted)) {
|
||||
input.value = formatted;
|
||||
}
|
||||
|
||||
emitChange(formatted);
|
||||
setValue(formatted);
|
||||
};
|
||||
|
||||
const onFocus = (event: Event) => {
|
||||
|
@ -1,7 +1,9 @@
|
||||
import { isPromise, noop } from '.';
|
||||
|
||||
export type Interceptor = (...args: any[]) => Promise<boolean> | boolean;
|
||||
|
||||
export function callInterceptor(options: {
|
||||
interceptor?: (...args: any[]) => Promise<boolean> | boolean;
|
||||
interceptor?: Interceptor;
|
||||
args?: any[];
|
||||
done: () => void;
|
||||
canceled?: () => void;
|
||||
|
Loading…
x
Reference in New Issue
Block a user