feat: 新增 InputNumber 组件支持长按加减功能 (#910)

This commit is contained in:
Chiko 2025-03-04 21:25:34 +08:00 committed by GitHub
parent 15613b393a
commit 94370876e4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 74 additions and 13 deletions

View File

@ -98,6 +98,7 @@ function handleChange({ value }) {
```
## 异步变更
通过 `before-change` 可以在输入值变化前进行校验和拦截。
```html
@ -123,7 +124,13 @@ const beforeChange: InputNumberBeforeChange = (value) => {
}
```
## 长按加减
设置 `long-press` 属性,允许长按加减。
```html
<wd-input-number v-model="value" long-press @change="handleChange" />
```
## Attributes
@ -145,6 +152,7 @@ const beforeChange: InputNumberBeforeChange = (value) => {
| disable-minus | 禁用减少按钮 | boolean | - | false | 0.2.14 |
| adjustPosition | 原生属性,键盘弹起时,是否自动上推页面 | boolean | - | true | 1.3.11 |
| before-change | 输入框值改变前触发,返回 false 会阻止输入框值改变,支持返回 `Promise` | `(value: number \| string) => boolean \| Promise<boolean>` | - | - | 1.6.0 |
| long-press | 是否允许长按进行加减 | boolean | - | false | $LOWEST_VERSION$ |
## Events

View File

@ -36,6 +36,9 @@
<demo-block title="异步变更">
<wd-input-number v-model="value11" :before-change="beforeChange" />
</demo-block>
<demo-block title="长按加减">
<wd-input-number v-model="value12" long-press @change="handleChange12" />
</demo-block>
</page-wraper>
</template>
<script lang="ts" setup>
@ -55,6 +58,7 @@ const value8 = ref<number>(2)
const value9 = ref<string>('')
const value10 = ref<number>(1)
const value11 = ref<number>(1)
const value12 = ref<number>(1)
function handleChange1({ value }: any) {
console.log(value)
@ -83,6 +87,9 @@ function handleChange8({ value }: any) {
function handleChange9({ value }: any) {
console.log(value)
}
function handleChange12({ value }: any) {
console.log(value)
}
const beforeChange: InputNumberBeforeChange = (value) => {
loading({ msg: `正在更新到${value}...` })

View File

@ -17,6 +17,8 @@ import { baseProps, makeBooleanProp, makeNumberProp, makeNumericProp, makeRequir
*/
export type InputNumberBeforeChange = (value: number | string) => boolean | Promise<boolean>
export type OperationType = 'add' | 'sub'
/**
*
* Input: 用户输入事件
@ -96,5 +98,9 @@ export const inputNumberProps = {
/**
* `false` `Promise`
*/
beforeChange: Function as PropType<InputNumberBeforeChange>
beforeChange: Function as PropType<InputNumberBeforeChange>,
/**
*
*/
longPress: makeBooleanProp(false)
}

View File

@ -1,7 +1,12 @@
<template>
<view :class="`wd-input-number ${customClass} ${disabled ? 'is-disabled' : ''} ${withoutInput ? 'is-without-input' : ''}`" :style="customStyle">
<!-- 减号按钮 -->
<view :class="`wd-input-number__action ${minDisabled || disableMinus ? 'is-disabled' : ''}`" @click="sub">
<view
:class="`wd-input-number__action ${minDisabled || disableMinus ? 'is-disabled' : ''}`"
@click="handleClick('sub')"
@touchstart="handleTouchStart('sub')"
@touchend.stop="handleTouchEnd"
>
<wd-icon name="decrease" custom-class="wd-input-number__action-icon"></wd-icon>
</view>
<!-- 输入框 -->
@ -21,7 +26,12 @@
<view class="wd-input-number__input-border"></view>
</view>
<!-- 加号按钮 -->
<view :class="`wd-input-number__action ${maxDisabled || disablePlus ? 'is-disabled' : ''}`" @click="add">
<view
:class="`wd-input-number__action ${maxDisabled || disablePlus ? 'is-disabled' : ''}`"
@click="handleClick('add')"
@touchstart="handleTouchStart('add')"
@touchend.stop="handleTouchEnd"
>
<wd-icon name="add" custom-class="wd-input-number__action-icon"></wd-icon>
</view>
</view>
@ -42,12 +52,13 @@ export default {
import wdIcon from '../wd-icon/wd-icon.vue'
import { computed, nextTick, ref, watch } from 'vue'
import { isDef, isEqual } from '../common/util'
import { inputNumberProps, InputNumberEventType } from './types'
import { inputNumberProps, InputNumberEventType, type OperationType } from './types'
import { callInterceptor } from '../common/interceptor'
const props = defineProps(inputNumberProps)
const emit = defineEmits(['focus', 'blur', 'change', 'update:modelValue'])
const inputValue = ref<string | number>(getInitValue()) //
let longPressTimer: ReturnType<typeof setTimeout> | null = null //
/**
* 判断数字是否达到最小值限制
@ -219,14 +230,10 @@ function changeValue(step: number) {
updateValue(value, InputNumberEventType.Button)
}
//
function sub() {
changeValue(-props.step)
}
//
function add() {
changeValue(props.step)
//
function handleClick(type: OperationType) {
const diff = type === 'add' ? props.step : -props.step
changeValue(diff)
}
function handleInput(event: any) {
@ -240,6 +247,39 @@ function handleBlur(event: any) {
emit('blur', { value })
}
//
function longPressStep(type: OperationType) {
clearlongPressTimer()
longPressTimer = setTimeout(() => {
handleClick(type)
longPressStep(type)
}, 250)
}
//
function handleTouchStart(type: OperationType) {
if (!props.longPress) return
clearlongPressTimer()
longPressTimer = setTimeout(() => {
handleClick(type)
longPressStep(type)
}, 600)
}
//
function handleTouchEnd() {
if (!props.longPress) return
clearlongPressTimer()
}
//
function clearlongPressTimer() {
if (longPressTimer) {
clearTimeout(longPressTimer)
longPressTimer = null
}
}
//
function handleFocus(event: any) {
emit('focus', event.detail)