更新:登录功能
This commit is contained in:
132
uni_modules/wot-design-uni/components/wd-input-number/index.scss
Normal file
132
uni_modules/wot-design-uni/components/wd-input-number/index.scss
Normal file
@@ -0,0 +1,132 @@
|
||||
@import "./../common/abstracts/_mixin.scss";
|
||||
@import "./../common/abstracts/variable.scss";
|
||||
|
||||
.wot-theme-dark {
|
||||
@include b(input-number) {
|
||||
@include e(action) {
|
||||
color: $-dark-color;
|
||||
@include when(disabled) {
|
||||
color: $-dark-color-gray;
|
||||
}
|
||||
}
|
||||
|
||||
@include e(input) {
|
||||
color: $-dark-color;
|
||||
}
|
||||
|
||||
@include when(disabled) {
|
||||
.wd-input-number__input {
|
||||
color: $-dark-color-gray;
|
||||
}
|
||||
.wd-input-number__sub,
|
||||
.wd-input-number__add {
|
||||
color: $-dark-color-gray;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include b(input-number) {
|
||||
display: inline-block;
|
||||
user-select: none;
|
||||
line-height: 1.15;
|
||||
|
||||
@include e(action) {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: $-input-number-btn-width;
|
||||
height: $-input-number-height;
|
||||
vertical-align: middle;
|
||||
color: $-input-number-icon-color;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
box-sizing: border-box;
|
||||
|
||||
// 左右加减号的边框
|
||||
&::after {
|
||||
position: absolute;
|
||||
content: "";
|
||||
width: calc(200% - 2px);
|
||||
height: calc(200% - 2px);
|
||||
left: 0;
|
||||
top: 0;
|
||||
border: 1px solid $-input-number-border-color;
|
||||
border-top-left-radius: calc($-input-number-radius * 2);
|
||||
border-bottom-left-radius: calc($-input-number-radius * 2);
|
||||
transform: scale(0.5);
|
||||
transform-origin: left top;
|
||||
}
|
||||
&:last-child::after {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
border-top-right-radius: calc($-input-number-radius * 2);
|
||||
border-bottom-right-radius: calc($-input-number-radius * 2);
|
||||
}
|
||||
@include when(disabled) {
|
||||
color: $-input-number-disabled-color;
|
||||
}
|
||||
}
|
||||
|
||||
@include e(inner) {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
@include e(input) {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: $-input-number-input-width;
|
||||
height: $-input-number-height;
|
||||
padding: 0 2px;
|
||||
box-sizing: border-box;
|
||||
z-index: 1;
|
||||
background: transparent;
|
||||
border: none;
|
||||
outline: none;
|
||||
text-align: center;
|
||||
color: $-input-number-color;
|
||||
font-size: $-input-number-fs;
|
||||
-webkit-appearance: none;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
@include e(input-border) {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: calc(200% - 2px);
|
||||
left: 0;
|
||||
top: 0;
|
||||
border-top: 1px solid $-input-number-border-color;
|
||||
border-bottom: 1px solid $-input-number-border-color;
|
||||
transform: scaleY(0.5);
|
||||
transform-origin: left top;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
@include edeep(action-icon) {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
font-size: $-input-number-icon-size;
|
||||
width: $-input-number-icon-size;
|
||||
height: $-input-number-icon-size;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
@include when(disabled) {
|
||||
.wd-input-number__input {
|
||||
color: $-input-number-disabled-color;
|
||||
z-index: inherit;
|
||||
}
|
||||
.wd-input-number__sub,
|
||||
.wd-input-number__add {
|
||||
color: $-input-number-disabled-color;
|
||||
}
|
||||
}
|
||||
@include when(without-input) {
|
||||
.wd-input-number__action:last-child::after {
|
||||
border-left: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
110
uni_modules/wot-design-uni/components/wd-input-number/types.ts
Normal file
110
uni_modules/wot-design-uni/components/wd-input-number/types.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* @Author: weisheng
|
||||
* @Date: 2024-03-15 20:40:34
|
||||
* @LastEditTime: 2025-06-21 18:23:35
|
||||
* @LastEditors: weisheng
|
||||
* @Description:
|
||||
* @FilePath: /wot-design-uni/src/uni_modules/wot-design-uni/components/wd-input-number/types.ts
|
||||
* 记得注释
|
||||
*/
|
||||
import type { ExtractPropTypes, PropType } from 'vue'
|
||||
import { baseProps, makeBooleanProp, makeNumberProp, makeNumericProp, makeRequiredProp, makeStringProp, numericProp } from '../common/props'
|
||||
|
||||
/**
|
||||
* 输入框值变化前的回调函数类型定义
|
||||
* @param value 输入框的新值
|
||||
* @returns 返回布尔值或Promise<boolean>,用于控制是否允许值的变化
|
||||
*/
|
||||
export type InputNumberBeforeChange = (value: number | string) => boolean | Promise<boolean>
|
||||
|
||||
export type OperationType = 'add' | 'sub'
|
||||
|
||||
export const inputNumberProps = {
|
||||
...baseProps,
|
||||
/**
|
||||
* 绑定值
|
||||
*/
|
||||
modelValue: makeRequiredProp(numericProp),
|
||||
/**
|
||||
* 最小值
|
||||
*/
|
||||
min: makeNumberProp(1),
|
||||
/**
|
||||
* 最大值
|
||||
*/
|
||||
max: makeNumberProp(Number.MAX_SAFE_INTEGER),
|
||||
/**
|
||||
* 步进值
|
||||
*/
|
||||
step: makeNumberProp(1),
|
||||
/**
|
||||
* 是否严格按照步进值递增或递减
|
||||
*/
|
||||
stepStrictly: makeBooleanProp(false),
|
||||
/**
|
||||
* 数值精度
|
||||
*/
|
||||
precision: makeNumericProp(0),
|
||||
/**
|
||||
* 是否禁用
|
||||
*/
|
||||
disabled: makeBooleanProp(false),
|
||||
/**
|
||||
* 是否禁用输入框
|
||||
*/
|
||||
disableInput: makeBooleanProp(false),
|
||||
/**
|
||||
* 是否禁用减号按钮
|
||||
*/
|
||||
disableMinus: makeBooleanProp(false),
|
||||
/**
|
||||
* 是否禁用加号按钮
|
||||
*/
|
||||
disablePlus: makeBooleanProp(false),
|
||||
/**
|
||||
* 是否不显示输入框
|
||||
*/
|
||||
withoutInput: makeBooleanProp(false),
|
||||
/**
|
||||
* 输入框宽度
|
||||
*/
|
||||
inputWidth: makeNumericProp(36),
|
||||
/**
|
||||
* 是否允许为空
|
||||
*/
|
||||
allowNull: makeBooleanProp(false),
|
||||
/**
|
||||
* 输入框占位符
|
||||
*/
|
||||
placeholder: makeStringProp(''),
|
||||
/**
|
||||
* 原生属性,键盘弹起时,是否自动上推页面
|
||||
*/
|
||||
adjustPosition: makeBooleanProp(true),
|
||||
/**
|
||||
* 输入值变化前的回调函数,返回 `false` 可阻止输入,支持返回 `Promise`
|
||||
*/
|
||||
beforeChange: Function as PropType<InputNumberBeforeChange>,
|
||||
/**
|
||||
* 是否开启长按加减手势
|
||||
*/
|
||||
longPress: makeBooleanProp(false),
|
||||
/**
|
||||
* 是否立即响应输入变化,false 时仅在失焦和按钮点击时更新
|
||||
*/
|
||||
immediateChange: makeBooleanProp(true),
|
||||
/**
|
||||
* 是否在初始化时更新 v-model 为修正后的值
|
||||
* true: 自动修正并更新 v-model
|
||||
* false: 保持原始值不修正,但仍会进行显示格式化
|
||||
*/
|
||||
updateOnInit: makeBooleanProp(true),
|
||||
/**
|
||||
* 输入框类型
|
||||
* number: 数字输入
|
||||
* digit: 整数输入
|
||||
*/
|
||||
inputType: makeStringProp<'number' | 'digit'>('digit')
|
||||
}
|
||||
|
||||
export type InputNumberProps = ExtractPropTypes<typeof inputNumberProps>
|
||||
@@ -0,0 +1,464 @@
|
||||
<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="handleClick('sub')"
|
||||
@touchstart="handleTouchStart('sub')"
|
||||
@touchend.stop="handleTouchEnd"
|
||||
>
|
||||
<wd-icon name="decrease" custom-class="wd-input-number__action-icon"></wd-icon>
|
||||
</view>
|
||||
<!-- 输入框 -->
|
||||
<view v-if="!withoutInput" class="wd-input-number__inner" @click.stop="">
|
||||
<input
|
||||
class="wd-input-number__input"
|
||||
:style="`${inputWidth ? 'width: ' + inputWidth : ''}`"
|
||||
:type="inputType"
|
||||
:input-mode="precision ? 'decimal' : 'numeric'"
|
||||
:disabled="disabled || disableInput"
|
||||
:value="String(inputValue)"
|
||||
:placeholder="placeholder"
|
||||
:adjust-position="adjustPosition"
|
||||
@input="handleInput"
|
||||
@focus="handleFocus"
|
||||
@blur="handleBlur"
|
||||
/>
|
||||
<view class="wd-input-number__input-border"></view>
|
||||
</view>
|
||||
<!-- 加号按钮 -->
|
||||
<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>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'wd-input-number',
|
||||
options: {
|
||||
virtualHost: true,
|
||||
addGlobalClass: true,
|
||||
styleIsolation: 'shared'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import wdIcon from '../wd-icon/wd-icon.vue'
|
||||
import { computed, nextTick, ref, watch } from 'vue'
|
||||
import { isDef, isEqual } from '../common/util'
|
||||
import { inputNumberProps, type OperationType } from './types'
|
||||
import { callInterceptor } from '../common/interceptor'
|
||||
|
||||
const props = defineProps(inputNumberProps)
|
||||
const emit = defineEmits<{
|
||||
/**
|
||||
* 数值变化事件
|
||||
*/
|
||||
(e: 'change', value: { value: number | string }): void
|
||||
/**
|
||||
* 输入框聚焦事件
|
||||
*/
|
||||
(e: 'focus', detail: any): void
|
||||
/**
|
||||
* 输入框失焦事件
|
||||
*/
|
||||
(e: 'blur', value: { value: string | number }): void
|
||||
/**
|
||||
* v-model 更新事件
|
||||
*/
|
||||
(e: 'update:modelValue', value: number | string): void
|
||||
}>()
|
||||
const inputValue = ref<string | number>(getInitValue())
|
||||
let longPressTimer: ReturnType<typeof setTimeout> | null = null
|
||||
|
||||
/**
|
||||
* 判断数字是否达到最小值限制
|
||||
*/
|
||||
const minDisabled = computed(() => {
|
||||
const val = toNumber(inputValue.value)
|
||||
return props.disabled || val <= props.min || addStep(val, -props.step) < props.min
|
||||
})
|
||||
|
||||
/**
|
||||
* 判断数字是否达到最大值限制
|
||||
*/
|
||||
const maxDisabled = computed(() => {
|
||||
const val = toNumber(inputValue.value)
|
||||
return props.disabled || val >= props.max || addStep(val, props.step) > props.max
|
||||
})
|
||||
|
||||
// 监听 modelValue 变化
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(val) => {
|
||||
inputValue.value = formatValue(val)
|
||||
}
|
||||
)
|
||||
|
||||
// 监听 max, min, precision 变化时重新格式化当前值
|
||||
watch([() => props.max, () => props.min, () => props.precision], () => {
|
||||
const val = toNumber(inputValue.value)
|
||||
inputValue.value = formatValue(val)
|
||||
})
|
||||
|
||||
/**
|
||||
* 获取初始值
|
||||
*/
|
||||
function getInitValue() {
|
||||
if (!props.updateOnInit) {
|
||||
// 不自动修正时,仅做显示格式化,不修正值
|
||||
return formatDisplay(props.modelValue)
|
||||
}
|
||||
|
||||
const formatted = formatValue(props.modelValue)
|
||||
|
||||
// 如果格式化后的值与原始值不同,同步到外部
|
||||
if (!isEqual(String(formatted), String(props.modelValue))) {
|
||||
emit('update:modelValue', formatted)
|
||||
}
|
||||
return formatted
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数字的小数位数
|
||||
*/
|
||||
function getPrecision(val?: number) {
|
||||
if (!isDef(val)) return 0
|
||||
const str = val.toString()
|
||||
const dotIndex = str.indexOf('.')
|
||||
return dotIndex === -1 ? 0 : str.length - dotIndex - 1
|
||||
}
|
||||
|
||||
/**
|
||||
* 按指定精度处理数值
|
||||
*/
|
||||
function toPrecision(val: number) {
|
||||
const precision = Number(props.precision)
|
||||
return Math.round(val * Math.pow(10, precision)) / Math.pow(10, precision)
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字符串或数字转换为标准数值
|
||||
*/
|
||||
function toNumber(val: string | number): number {
|
||||
// 空值处理
|
||||
if (props.allowNull && (!isDef(val) || val === '')) {
|
||||
return NaN
|
||||
}
|
||||
|
||||
if (!isDef(val) || val === '') {
|
||||
return props.min
|
||||
}
|
||||
|
||||
let str = String(val)
|
||||
|
||||
// 处理中间输入状态
|
||||
if (str.endsWith('.')) str = str.slice(0, -1)
|
||||
if (str.startsWith('.')) str = '0' + str
|
||||
if (str.startsWith('-.')) str = '-0' + str.substring(1)
|
||||
if (str === '-' || str === '') return props.min
|
||||
|
||||
let num = Number(str)
|
||||
if (isNaN(num)) num = props.min
|
||||
|
||||
return normalizeValue(num)
|
||||
}
|
||||
|
||||
/**
|
||||
* 标准化数值(应用步进、边界、精度规则)
|
||||
*/
|
||||
function normalizeValue(val: number): number {
|
||||
let result = val
|
||||
|
||||
// 严格步进
|
||||
if (props.stepStrictly) {
|
||||
const stepPrecision = getPrecision(props.step)
|
||||
const factor = Math.pow(10, stepPrecision)
|
||||
result = (Math.round(result / props.step) * factor * props.step) / factor
|
||||
}
|
||||
|
||||
// 边界限制
|
||||
if (props.stepStrictly) {
|
||||
result = applyStrictBounds(result, props.min, props.max)
|
||||
} else {
|
||||
result = Math.min(Math.max(result, props.min), props.max)
|
||||
}
|
||||
|
||||
// 精度处理
|
||||
if (isDef(props.precision)) {
|
||||
result = toPrecision(result)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* 严格步进模式下的边界处理
|
||||
*/
|
||||
function applyStrictBounds(val: number, min: number, max: number): number {
|
||||
if (val >= min && val <= max) return val
|
||||
|
||||
const stepPrecision = getPrecision(props.step)
|
||||
const factor = Math.pow(10, stepPrecision)
|
||||
|
||||
if (val < min) {
|
||||
const minSteps = Math.ceil((min * factor) / (props.step * factor))
|
||||
const candidate = toPrecision((minSteps * props.step * factor) / factor)
|
||||
if (candidate > max) {
|
||||
const maxSteps = Math.floor((max * factor) / (props.step * factor))
|
||||
return toPrecision((maxSteps * props.step * factor) / factor)
|
||||
}
|
||||
return candidate
|
||||
}
|
||||
|
||||
if (val > max) {
|
||||
const maxSteps = Math.floor((max * factor) / (props.step * factor))
|
||||
const candidate = toPrecision((maxSteps * props.step * factor) / factor)
|
||||
if (candidate < min) {
|
||||
const minSteps = Math.ceil((min * factor) / (props.step * factor))
|
||||
return toPrecision((minSteps * props.step * factor) / factor)
|
||||
}
|
||||
return candidate
|
||||
}
|
||||
|
||||
return val
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化值用于显示(包含修正逻辑)
|
||||
*/
|
||||
function formatValue(val: string | number): string | number {
|
||||
if (props.allowNull && (!isDef(val) || val === '')) {
|
||||
return ''
|
||||
}
|
||||
|
||||
const num = toNumber(val)
|
||||
const precision = Number(props.precision)
|
||||
if (!isDef(props.precision)) {
|
||||
return num
|
||||
}
|
||||
return precision === 0 ? Number(num.toFixed(0)) : num.toFixed(precision)
|
||||
}
|
||||
|
||||
/**
|
||||
* 仅做显示格式化,不包含值修正逻辑
|
||||
*/
|
||||
function formatDisplay(val: string | number): string | number {
|
||||
if (props.allowNull && (!isDef(val) || val === '')) {
|
||||
return ''
|
||||
}
|
||||
|
||||
if (!isDef(val) || val === '') {
|
||||
return props.min
|
||||
}
|
||||
|
||||
let num = Number(val)
|
||||
if (isNaN(num)) {
|
||||
return props.min
|
||||
}
|
||||
|
||||
const precision = Number(props.precision)
|
||||
if (!isDef(props.precision)) {
|
||||
return num
|
||||
}
|
||||
return precision === 0 ? Number(num.toFixed(0)) : num.toFixed(precision)
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否为中间输入状态
|
||||
*/
|
||||
function isIntermediate(val: string): boolean {
|
||||
if (!val) return false
|
||||
const str = String(val)
|
||||
return str.endsWith('.') || str.startsWith('.') || str.startsWith('-.') || str === '-' || (Number(props.precision) > 0 && str.indexOf('.') === -1)
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理输入值
|
||||
*/
|
||||
function cleanInput(val: string): string {
|
||||
if (!val) return ''
|
||||
|
||||
// 清理非数字、小数点、负号
|
||||
let cleaned = val.replace(/[^\d.-]/g, '')
|
||||
|
||||
// 处理负号,保证负号只出现在最前面
|
||||
const hasNegative = cleaned.startsWith('-')
|
||||
cleaned = cleaned.replace(/-/g, '')
|
||||
if (hasNegative) cleaned = '-' + cleaned
|
||||
|
||||
// 处理小数点
|
||||
const precision = Number(props.precision)
|
||||
if (precision > 0) {
|
||||
const parts = cleaned.split('.')
|
||||
if (parts.length > 2) {
|
||||
cleaned = parts[0] + '.' + parts.slice(1).join('')
|
||||
}
|
||||
} else {
|
||||
cleaned = cleaned.split('.')[0]
|
||||
}
|
||||
|
||||
// 处理以点开头的情况
|
||||
if (cleaned.startsWith('.')) return '0' + cleaned
|
||||
if (cleaned.startsWith('-.')) return '-0' + cleaned.substring(1)
|
||||
|
||||
return cleaned
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新值并触发事件
|
||||
*/
|
||||
function updateValue(val: string | number) {
|
||||
// 空值处理
|
||||
if (props.allowNull && (!isDef(val) || val === '')) {
|
||||
if (isEqual('', String(props.modelValue))) {
|
||||
inputValue.value = ''
|
||||
return
|
||||
}
|
||||
|
||||
const doUpdate = () => {
|
||||
inputValue.value = ''
|
||||
emit('update:modelValue', '')
|
||||
emit('change', { value: '' })
|
||||
}
|
||||
|
||||
callInterceptor(props.beforeChange, { args: [''], done: doUpdate })
|
||||
return
|
||||
}
|
||||
|
||||
const num = toNumber(val)
|
||||
const display = formatValue(val)
|
||||
|
||||
if (isEqual(String(num), String(props.modelValue))) {
|
||||
inputValue.value = display
|
||||
return
|
||||
}
|
||||
|
||||
const doUpdate = () => {
|
||||
inputValue.value = display
|
||||
emit('update:modelValue', num)
|
||||
emit('change', { value: num })
|
||||
}
|
||||
|
||||
callInterceptor(props.beforeChange, { args: [num], done: doUpdate })
|
||||
}
|
||||
|
||||
/**
|
||||
* 按步进值增减
|
||||
*/
|
||||
function addStep(val: string | number, step: number) {
|
||||
const num = Number(val)
|
||||
if (isNaN(num)) return normalizeValue(props.min)
|
||||
|
||||
const precision = Math.max(getPrecision(num), getPrecision(step))
|
||||
const factor = Math.pow(10, precision)
|
||||
const result = (num * factor + step * factor) / factor
|
||||
return normalizeValue(result)
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理按钮点击
|
||||
*/
|
||||
function handleClick(type: OperationType) {
|
||||
const step = type === 'add' ? props.step : -props.step
|
||||
if ((step < 0 && (minDisabled.value || props.disableMinus)) || (step > 0 && (maxDisabled.value || props.disablePlus))) return
|
||||
|
||||
const newVal = addStep(inputValue.value, step)
|
||||
updateValue(newVal)
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理输入事件
|
||||
*/
|
||||
function handleInput(event: any) {
|
||||
const rawVal = event.detail.value || ''
|
||||
|
||||
// 立即更新显示
|
||||
inputValue.value = rawVal
|
||||
|
||||
nextTick(() => {
|
||||
// 空值处理
|
||||
if (rawVal === '') {
|
||||
inputValue.value = ''
|
||||
if (props.immediateChange && props.allowNull) {
|
||||
updateValue('')
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 清理输入
|
||||
const cleaned = cleanInput(rawVal)
|
||||
|
||||
// 中间状态处理
|
||||
if (Number(props.precision) > 0 && isIntermediate(cleaned)) {
|
||||
inputValue.value = cleaned
|
||||
return
|
||||
}
|
||||
|
||||
// 正常输入处理
|
||||
inputValue.value = cleaned
|
||||
if (props.immediateChange) {
|
||||
updateValue(cleaned)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理失焦事件
|
||||
*/
|
||||
function handleBlur(event: any) {
|
||||
const val = event.detail.value || ''
|
||||
updateValue(val)
|
||||
emit('blur', { value: val })
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理聚焦事件
|
||||
*/
|
||||
function handleFocus(event: any) {
|
||||
emit('focus', event.detail)
|
||||
}
|
||||
|
||||
/**
|
||||
* 长按逻辑
|
||||
*/
|
||||
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
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './index.scss';
|
||||
</style>
|
||||
Reference in New Issue
Block a user