Commit a6fa1356 authored by 马旭烽's avatar 马旭烽

feat: 临时存放h5组件输入预检测逻辑

parent d5650858
import { showToast } from '@tarojs/taro';
import { showToast } from '@tarojs/taro';
import type { InputRuleItem } from './type';
/** 规则校验整数 */
export const numberRule: InputRuleItem = {
type: 'number',
check(v) {
const num = Number(v);
return !Number.isNaN(num);
},
errorTrigger(v) {
showToast({
title: '请输入数字',
icon: 'none',
})
},
}
/** 规则校验正整数 */
export const positiveRule: InputRuleItem = {
type: 'positive',
check(v) {
const num = Number(v);
if (Number.isNaN(num)) return false;
if (num <= 0) return false;
return true;
},
errorTrigger(v) {
showToast({
title: '请输入正整数',
icon: 'none',
})
},
}
/** 规则校验负整数 */
export const negativeRule: InputRuleItem = {
type: 'negative',
check(v) {
const num = Number(v);
if (Number.isNaN(num)) return false;
if (num >= 0) return false;
return true;
},
errorTrigger(v) {
showToast({
title: '请输入负整数',
icon: 'none',
})
},
};
import React from 'react';
import React from 'react';
import { Input, } from '@linkseeks/god-taro-library';
import { useRule } from './server';
import type { InputXProps } from './type';
function InputX (props: InputXProps ) {
const { rules, onChange, onBlur, ...inputProps } = props;
const changeWrapper = useRule({
rules,
onChange,
onBlur,
})
return <Input {...changeWrapper} {...inputProps} />
};
export default InputX;
export * from './type';
export * from './modal';
export * from './util';
export * from './helper';
export * from './server';
import type { BaseRuleItem, InputRuleItem } from './type';
import type { BaseRuleItem, InputRuleItem } from './type';
class RuleManager<RI extends BaseRuleItem<unknown, unknown>>{
public rules: RI | null;
public cur: RI | null;
constructor() {
this.rules = null;
this.cur = null;
}
pushRule(rule: RI) {
if (null === this.rules || null === this.cur) {
this.rules = rule;
this.cur = rule;
} else {
this.cur.next = rule;
}
return this;
}
checkChain(value: unknown) {
let result = true, cur: RI | null = this.rules;
while (true === result && cur) {
result = !!(this.cur?.check(value));
if (!result && this.cur?.errorTrigger) {
this.cur.errorTrigger(value);
}
cur = cur?.next as RI;
};
return result;
}
}
export class InputRuleManager extends RuleManager<InputRuleItem> {
}
import { useMemo, } from 'react';
import { useMemo, } from 'react';
import { InputRuleManager } from './modal';
import { noop, emptyList, noChange , createBefore } from './util';
import type { useRuleInProps } from './type';
export const useRule = (props: useRuleInProps) => {
const {
rules = emptyList,
onChange = noop,
onBlur = noop,
} = props;
const ruleManager = useMemo(() => {
const formatRules = Array.isArray(rules) ? rules.filter(noChange) : [rules].filter(noChange);
const inputRuleManager = new InputRuleManager();
formatRules.forEach(rule => {
inputRuleManager.pushRule(rule);
});
return inputRuleManager;
}, [rules]);
const changeWrapper = useMemo(() => {
// 实际设计并不好,我没有考虑到组件什么时候调用,什么时候检测,只是对可能 change 的方法做了一层 拦截处理
const beforeWrapper = (fn: typeof onChange | typeof onBlur) => createBefore(fn, ruleManager.checkChain.apply(ruleManager));
return {
onChange: beforeWrapper(onChange),
onBlur: beforeWrapper(onBlur),
}
}, [onChange, onBlur, ruleManager])
return changeWrapper;
};
import type { ComponentProps } from 'react';
import type { ComponentProps } from 'react';
import { Input, } from '@linkseeks/god-taro-library';
/** 基础校验规则 */
export interface BaseRuleItem<T, V> {
type: T,
/** 如果有异常,返回 false */
check: (v: V) => boolean,
/** 异常触发器 */
errorTrigger?: (v: V) => void,
next?: BaseRuleItem<T, V>,
};
type OriginInputProps = ComponentProps<typeof Input>;
/**
* number 输入必须符合整数
* positive 正整数
* negative 负整数
*/
export type InputRuleItemType= 'number' | 'positive' | 'negative';
export interface InputRuleItem extends BaseRuleItem<InputRuleItemType, string> {
}
export interface InputXProps extends OriginInputProps {
/** 内置常用的校验器 */
rules?: InputRuleItem | InputRuleItem[];
}
export interface useRuleInProps extends Pick<InputXProps, "onChange"|"onBlur"|"rules"> {
}
/**--------------------- 函数相关 */
/**--------------------- 函数相关 */
export const noop = () => { };
export const emptyList = [];
export const noChange = item => item;
export const createBefore = <F extends Function>(fn: F, before: (args: any[]) => boolean) => new Proxy(fn, {
apply: function (target, thisArg, args) {
return before(args) && target.apply(thisArg, args)
}
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment