mirror of
https://gitee.com/wot-design-uni/wot-design-uni.git
synced 2025-12-06 17:18:40 +08:00
feat: ✨ 新增 InputNumber 组件支持长按加减功能 (#910)
This commit is contained in:
parent
15613b393a
commit
94370876e4
@ -98,6 +98,7 @@ function handleChange({ value }) {
|
|||||||
```
|
```
|
||||||
|
|
||||||
## 异步变更
|
## 异步变更
|
||||||
|
|
||||||
通过 `before-change` 可以在输入值变化前进行校验和拦截。
|
通过 `before-change` 可以在输入值变化前进行校验和拦截。
|
||||||
|
|
||||||
```html
|
```html
|
||||||
@ -123,7 +124,13 @@ const beforeChange: InputNumberBeforeChange = (value) => {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 长按加减
|
||||||
|
|
||||||
|
设置 `long-press` 属性,允许长按加减。
|
||||||
|
|
||||||
|
```html
|
||||||
|
<wd-input-number v-model="value" long-press @change="handleChange" />
|
||||||
|
```
|
||||||
|
|
||||||
## Attributes
|
## Attributes
|
||||||
|
|
||||||
@ -145,6 +152,7 @@ const beforeChange: InputNumberBeforeChange = (value) => {
|
|||||||
| disable-minus | 禁用减少按钮 | boolean | - | false | 0.2.14 |
|
| disable-minus | 禁用减少按钮 | boolean | - | false | 0.2.14 |
|
||||||
| adjustPosition | 原生属性,键盘弹起时,是否自动上推页面 | boolean | - | true | 1.3.11 |
|
| adjustPosition | 原生属性,键盘弹起时,是否自动上推页面 | boolean | - | true | 1.3.11 |
|
||||||
| before-change | 输入框值改变前触发,返回 false 会阻止输入框值改变,支持返回 `Promise` | `(value: number \| string) => boolean \| Promise<boolean>` | - | - | 1.6.0 |
|
| before-change | 输入框值改变前触发,返回 false 会阻止输入框值改变,支持返回 `Promise` | `(value: number \| string) => boolean \| Promise<boolean>` | - | - | 1.6.0 |
|
||||||
|
| long-press | 是否允许长按进行加减 | boolean | - | false | $LOWEST_VERSION$ |
|
||||||
|
|
||||||
|
|
||||||
## Events
|
## Events
|
||||||
|
|||||||
@ -36,6 +36,9 @@
|
|||||||
<demo-block title="异步变更">
|
<demo-block title="异步变更">
|
||||||
<wd-input-number v-model="value11" :before-change="beforeChange" />
|
<wd-input-number v-model="value11" :before-change="beforeChange" />
|
||||||
</demo-block>
|
</demo-block>
|
||||||
|
<demo-block title="长按加减">
|
||||||
|
<wd-input-number v-model="value12" long-press @change="handleChange12" />
|
||||||
|
</demo-block>
|
||||||
</page-wraper>
|
</page-wraper>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@ -55,6 +58,7 @@ const value8 = ref<number>(2)
|
|||||||
const value9 = ref<string>('')
|
const value9 = ref<string>('')
|
||||||
const value10 = ref<number>(1)
|
const value10 = ref<number>(1)
|
||||||
const value11 = ref<number>(1)
|
const value11 = ref<number>(1)
|
||||||
|
const value12 = ref<number>(1)
|
||||||
|
|
||||||
function handleChange1({ value }: any) {
|
function handleChange1({ value }: any) {
|
||||||
console.log(value)
|
console.log(value)
|
||||||
@ -83,6 +87,9 @@ function handleChange8({ value }: any) {
|
|||||||
function handleChange9({ value }: any) {
|
function handleChange9({ value }: any) {
|
||||||
console.log(value)
|
console.log(value)
|
||||||
}
|
}
|
||||||
|
function handleChange12({ value }: any) {
|
||||||
|
console.log(value)
|
||||||
|
}
|
||||||
|
|
||||||
const beforeChange: InputNumberBeforeChange = (value) => {
|
const beforeChange: InputNumberBeforeChange = (value) => {
|
||||||
loading({ msg: `正在更新到${value}...` })
|
loading({ msg: `正在更新到${value}...` })
|
||||||
|
|||||||
@ -17,6 +17,8 @@ import { baseProps, makeBooleanProp, makeNumberProp, makeNumericProp, makeRequir
|
|||||||
*/
|
*/
|
||||||
export type InputNumberBeforeChange = (value: number | string) => boolean | Promise<boolean>
|
export type InputNumberBeforeChange = (value: number | string) => boolean | Promise<boolean>
|
||||||
|
|
||||||
|
export type OperationType = 'add' | 'sub'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 输入数字组件事件类型枚举
|
* 输入数字组件事件类型枚举
|
||||||
* Input: 用户输入事件
|
* Input: 用户输入事件
|
||||||
@ -96,5 +98,9 @@ export const inputNumberProps = {
|
|||||||
/**
|
/**
|
||||||
* 输入值变化前的回调函数,返回 `false` 可阻止输入,支持返回 `Promise`
|
* 输入值变化前的回调函数,返回 `false` 可阻止输入,支持返回 `Promise`
|
||||||
*/
|
*/
|
||||||
beforeChange: Function as PropType<InputNumberBeforeChange>
|
beforeChange: Function as PropType<InputNumberBeforeChange>,
|
||||||
|
/**
|
||||||
|
* 是否开启长按加减手势
|
||||||
|
*/
|
||||||
|
longPress: makeBooleanProp(false)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :class="`wd-input-number ${customClass} ${disabled ? 'is-disabled' : ''} ${withoutInput ? 'is-without-input' : ''}`" :style="customStyle">
|
<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>
|
<wd-icon name="decrease" custom-class="wd-input-number__action-icon"></wd-icon>
|
||||||
</view>
|
</view>
|
||||||
<!-- 输入框 -->
|
<!-- 输入框 -->
|
||||||
@ -21,7 +26,12 @@
|
|||||||
<view class="wd-input-number__input-border"></view>
|
<view class="wd-input-number__input-border"></view>
|
||||||
</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>
|
<wd-icon name="add" custom-class="wd-input-number__action-icon"></wd-icon>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -42,12 +52,13 @@ export default {
|
|||||||
import wdIcon from '../wd-icon/wd-icon.vue'
|
import wdIcon from '../wd-icon/wd-icon.vue'
|
||||||
import { computed, nextTick, ref, watch } from 'vue'
|
import { computed, nextTick, ref, watch } from 'vue'
|
||||||
import { isDef, isEqual } from '../common/util'
|
import { isDef, isEqual } from '../common/util'
|
||||||
import { inputNumberProps, InputNumberEventType } from './types'
|
import { inputNumberProps, InputNumberEventType, type OperationType } from './types'
|
||||||
import { callInterceptor } from '../common/interceptor'
|
import { callInterceptor } from '../common/interceptor'
|
||||||
|
|
||||||
const props = defineProps(inputNumberProps)
|
const props = defineProps(inputNumberProps)
|
||||||
const emit = defineEmits(['focus', 'blur', 'change', 'update:modelValue'])
|
const emit = defineEmits(['focus', 'blur', 'change', 'update:modelValue'])
|
||||||
const inputValue = ref<string | number>(getInitValue()) // 输入框的值
|
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)
|
updateValue(value, InputNumberEventType.Button)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 减少值
|
// 增减值
|
||||||
function sub() {
|
function handleClick(type: OperationType) {
|
||||||
changeValue(-props.step)
|
const diff = type === 'add' ? props.step : -props.step
|
||||||
}
|
changeValue(diff)
|
||||||
|
|
||||||
// 增加值
|
|
||||||
function add() {
|
|
||||||
changeValue(props.step)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleInput(event: any) {
|
function handleInput(event: any) {
|
||||||
@ -240,6 +247,39 @@ function handleBlur(event: any) {
|
|||||||
emit('blur', { value })
|
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) {
|
function handleFocus(event: any) {
|
||||||
emit('focus', event.detail)
|
emit('focus', event.detail)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user