Skip to content

Commit 9437087

Browse files
authored
feat: ✨ 新增 InputNumber 组件支持长按加减功能 (#910)
1 parent 15613b3 commit 9437087

4 files changed

Lines changed: 74 additions & 13 deletions

File tree

docs/component/input-number.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ function handleChange({ value }) {
9898
```
9999

100100
## 异步变更
101+
101102
通过 `before-change` 可以在输入值变化前进行校验和拦截。
102103

103104
```html
@@ -123,7 +124,13 @@ const beforeChange: InputNumberBeforeChange = (value) => {
123124
}
124125
```
125126

126-
127+
## 长按加减
128+
129+
设置 `long-press` 属性,允许长按加减。
130+
131+
```html
132+
<wd-input-number v-model="value" long-press @change="handleChange" />
133+
```
127134

128135
## Attributes
129136

@@ -145,6 +152,7 @@ const beforeChange: InputNumberBeforeChange = (value) => {
145152
| disable-minus | 禁用减少按钮 | boolean | - | false | 0.2.14 |
146153
| adjustPosition | 原生属性,键盘弹起时,是否自动上推页面 | boolean | - | true | 1.3.11 |
147154
| before-change | 输入框值改变前触发,返回 false 会阻止输入框值改变,支持返回 `Promise` | `(value: number \| string) => boolean \| Promise<boolean>` | - | - | 1.6.0 |
155+
| long-press | 是否允许长按进行加减 | boolean | - | false | $LOWEST_VERSION$ |
148156

149157

150158
## Events

src/pages/inputNumber/Index.vue

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636
<demo-block title="异步变更">
3737
<wd-input-number v-model="value11" :before-change="beforeChange" />
3838
</demo-block>
39+
<demo-block title="长按加减">
40+
<wd-input-number v-model="value12" long-press @change="handleChange12" />
41+
</demo-block>
3942
</page-wraper>
4043
</template>
4144
<script lang="ts" setup>
@@ -55,6 +58,7 @@ const value8 = ref<number>(2)
5558
const value9 = ref<string>('')
5659
const value10 = ref<number>(1)
5760
const value11 = ref<number>(1)
61+
const value12 = ref<number>(1)
5862
5963
function handleChange1({ value }: any) {
6064
console.log(value)
@@ -83,6 +87,9 @@ function handleChange8({ value }: any) {
8387
function handleChange9({ value }: any) {
8488
console.log(value)
8589
}
90+
function handleChange12({ value }: any) {
91+
console.log(value)
92+
}
8693
8794
const beforeChange: InputNumberBeforeChange = (value) => {
8895
loading({ msg: `正在更新到${value}...` })

src/uni_modules/wot-design-uni/components/wd-input-number/types.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import { baseProps, makeBooleanProp, makeNumberProp, makeNumericProp, makeRequir
1717
*/
1818
export type InputNumberBeforeChange = (value: number | string) => boolean | Promise<boolean>
1919

20+
export type OperationType = 'add' | 'sub'
21+
2022
/**
2123
* 输入数字组件事件类型枚举
2224
* Input: 用户输入事件
@@ -96,5 +98,9 @@ export const inputNumberProps = {
9698
/**
9799
* 输入值变化前的回调函数,返回 `false` 可阻止输入,支持返回 `Promise`
98100
*/
99-
beforeChange: Function as PropType<InputNumberBeforeChange>
101+
beforeChange: Function as PropType<InputNumberBeforeChange>,
102+
/**
103+
* 是否开启长按加减手势
104+
*/
105+
longPress: makeBooleanProp(false)
100106
}

src/uni_modules/wot-design-uni/components/wd-input-number/wd-input-number.vue

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
<template>
22
<view :class="`wd-input-number ${customClass} ${disabled ? 'is-disabled' : ''} ${withoutInput ? 'is-without-input' : ''}`" :style="customStyle">
33
<!-- 减号按钮 -->
4-
<view :class="`wd-input-number__action ${minDisabled || disableMinus ? 'is-disabled' : ''}`" @click="sub">
4+
<view
5+
:class="`wd-input-number__action ${minDisabled || disableMinus ? 'is-disabled' : ''}`"
6+
@click="handleClick('sub')"
7+
@touchstart="handleTouchStart('sub')"
8+
@touchend.stop="handleTouchEnd"
9+
>
510
<wd-icon name="decrease" custom-class="wd-input-number__action-icon"></wd-icon>
611
</view>
712
<!-- 输入框 -->
@@ -21,7 +26,12 @@
2126
<view class="wd-input-number__input-border"></view>
2227
</view>
2328
<!-- 加号按钮 -->
24-
<view :class="`wd-input-number__action ${maxDisabled || disablePlus ? 'is-disabled' : ''}`" @click="add">
29+
<view
30+
:class="`wd-input-number__action ${maxDisabled || disablePlus ? 'is-disabled' : ''}`"
31+
@click="handleClick('add')"
32+
@touchstart="handleTouchStart('add')"
33+
@touchend.stop="handleTouchEnd"
34+
>
2535
<wd-icon name="add" custom-class="wd-input-number__action-icon"></wd-icon>
2636
</view>
2737
</view>
@@ -42,12 +52,13 @@ export default {
4252
import wdIcon from '../wd-icon/wd-icon.vue'
4353
import { computed, nextTick, ref, watch } from 'vue'
4454
import { isDef, isEqual } from '../common/util'
45-
import { inputNumberProps, InputNumberEventType } from './types'
55+
import { inputNumberProps, InputNumberEventType, type OperationType } from './types'
4656
import { callInterceptor } from '../common/interceptor'
4757
4858
const props = defineProps(inputNumberProps)
4959
const emit = defineEmits(['focus', 'blur', 'change', 'update:modelValue'])
5060
const inputValue = ref<string | number>(getInitValue()) // 输入框的值
61+
let longPressTimer: ReturnType<typeof setTimeout> | null = null // 长按定时器
5162
5263
/**
5364
* 判断数字是否达到最小值限制
@@ -219,14 +230,10 @@ function changeValue(step: number) {
219230
updateValue(value, InputNumberEventType.Button)
220231
}
221232
222-
// 减少值
223-
function sub() {
224-
changeValue(-props.step)
225-
}
226-
227-
// 增加值
228-
function add() {
229-
changeValue(props.step)
233+
// 增减值
234+
function handleClick(type: OperationType) {
235+
const diff = type === 'add' ? props.step : -props.step
236+
changeValue(diff)
230237
}
231238
232239
function handleInput(event: any) {
@@ -240,6 +247,39 @@ function handleBlur(event: any) {
240247
emit('blur', { value })
241248
}
242249
250+
// 每隔一段时间,重新调用自身,达到长按加减效果
251+
function longPressStep(type: OperationType) {
252+
clearlongPressTimer()
253+
longPressTimer = setTimeout(() => {
254+
handleClick(type)
255+
longPressStep(type)
256+
}, 250)
257+
}
258+
259+
// 按下一段时间后,达到长按状态
260+
function handleTouchStart(type: OperationType) {
261+
if (!props.longPress) return
262+
clearlongPressTimer()
263+
longPressTimer = setTimeout(() => {
264+
handleClick(type)
265+
longPressStep(type)
266+
}, 600)
267+
}
268+
269+
// 触摸结束,清除定时器,停止长按加减
270+
function handleTouchEnd() {
271+
if (!props.longPress) return
272+
clearlongPressTimer()
273+
}
274+
275+
// 清除定时器
276+
function clearlongPressTimer() {
277+
if (longPressTimer) {
278+
clearTimeout(longPressTimer)
279+
longPressTimer = null
280+
}
281+
}
282+
243283
// 处理聚焦事件
244284
function handleFocus(event: any) {
245285
emit('focus', event.detail)

0 commit comments

Comments
 (0)