types(Form): use tsx (#8153)

This commit is contained in:
neverland 2021-02-14 16:51:37 +08:00 committed by GitHub
parent 08e928111b
commit 0fb0186fad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 23 deletions

View File

@ -42,6 +42,7 @@ import type {
FieldTextAlign, FieldTextAlign,
FieldClearTrigger, FieldClearTrigger,
FieldFormatTrigger, FieldFormatTrigger,
FieldValidateError,
FieldAutosizeConfig, FieldAutosizeConfig,
FieldValidateTrigger, FieldValidateTrigger,
} from './types'; } from './types';
@ -220,7 +221,7 @@ export default createComponent({
}; };
const validate = (rules = props.rules) => const validate = (rules = props.rules) =>
new Promise<{ name?: string; message: string } | void>((resolve) => { new Promise<FieldValidateError | void>((resolve) => {
resetValidation(); resetValidation();
if (rules) { if (rules) {
runRules(rules).then(() => { runRules(rules).then(() => {

View File

@ -20,6 +20,11 @@ export type FieldAutosizeConfig = {
minHeight?: number; minHeight?: number;
}; };
export type FieldValidateError = {
name?: string;
message: string;
};
export type FieldRule = { export type FieldRule = {
pattern?: RegExp; pattern?: RegExp;
trigger?: FieldValidateTrigger; trigger?: FieldValidateTrigger;

View File

@ -1,8 +1,20 @@
import { ComponentPublicInstance, PropType } from 'vue';
// Utils
import { createNamespace } from '../utils'; import { createNamespace } from '../utils';
// Composition
import { useChildren } from '@vant/use'; import { useChildren } from '@vant/use';
import { FORM_KEY } from '../composables/use-link-field'; import { FORM_KEY } from '../composables/use-link-field';
import { useExpose } from '../composables/use-expose'; import { useExpose } from '../composables/use-expose';
// Types
import type {
FieldTextAlign,
FieldValidateError,
FieldValidateTrigger,
} from '../field/types';
const [createComponent, bem] = createNamespace('form'); const [createComponent, bem] = createNamespace('form');
export default createComponent({ export default createComponent({
@ -12,17 +24,17 @@ export default createComponent({
readonly: Boolean, readonly: Boolean,
showError: Boolean, showError: Boolean,
labelWidth: [Number, String], labelWidth: [Number, String],
labelAlign: String, labelAlign: String as PropType<FieldTextAlign>,
inputAlign: String, inputAlign: String as PropType<FieldTextAlign>,
scrollToError: Boolean, scrollToError: Boolean,
validateFirst: Boolean, validateFirst: Boolean,
errorMessageAlign: String, errorMessageAlign: String as PropType<FieldTextAlign>,
submitOnEnter: { submitOnEnter: {
type: Boolean, type: Boolean,
default: true, default: true,
}, },
validateTrigger: { validateTrigger: {
type: String, type: String as PropType<FieldValidateTrigger>,
default: 'onBlur', default: 'onBlur',
}, },
showErrorMessage: { showErrorMessage: {
@ -34,18 +46,21 @@ export default createComponent({
emits: ['submit', 'failed'], emits: ['submit', 'failed'],
setup(props, { emit, slots }) { setup(props, { emit, slots }) {
const { children, linkChildren } = useChildren(FORM_KEY); const { children, linkChildren } = useChildren<
// eslint-disable-next-line
ComponentPublicInstance<{}, any>
>(FORM_KEY);
const getFieldsByNames = (names) => { const getFieldsByNames = (names?: string[]) => {
if (names) { if (names) {
return children.filter((field) => names.indexOf(field.name) !== -1); return children.filter((field) => names.indexOf(field.name) !== -1);
} }
return children; return children;
}; };
const validateSeq = (names) => const validateSeq = (names?: string[]) =>
new Promise((resolve, reject) => { new Promise<void>((resolve, reject) => {
const errors = []; const errors: FieldValidateError[] = [];
const fields = getFieldsByNames(names); const fields = getFieldsByNames(names);
fields fields
@ -53,7 +68,7 @@ export default createComponent({
(promise, field) => (promise, field) =>
promise.then(() => { promise.then(() => {
if (!errors.length) { if (!errors.length) {
return field.validate().then((error) => { return field.validate().then((error?: FieldValidateError) => {
if (error) { if (error) {
errors.push(error); errors.push(error);
} }
@ -71,8 +86,8 @@ export default createComponent({
}); });
}); });
const validateAll = (names) => const validateAll = (names?: string[]) =>
new Promise((resolve, reject) => { new Promise<void>((resolve, reject) => {
const fields = getFieldsByNames(names); const fields = getFieldsByNames(names);
Promise.all(fields.map((item) => item.validate())).then((errors) => { Promise.all(fields.map((item) => item.validate())).then((errors) => {
errors = errors.filter((item) => item); errors = errors.filter((item) => item);
@ -85,12 +100,12 @@ export default createComponent({
}); });
}); });
const validateField = (name) => { const validateField = (name: string) => {
const matched = children.filter((item) => item.name === name); const matched = children.filter((item) => item.name === name);
if (matched.length) { if (matched.length) {
return new Promise((resolve, reject) => { return new Promise<void>((resolve, reject) => {
matched[0].validate().then((error) => { matched[0].validate().then((error?: FieldValidateError) => {
if (error) { if (error) {
reject(error); reject(error);
} else { } else {
@ -103,15 +118,15 @@ export default createComponent({
return Promise.reject(); return Promise.reject();
}; };
const validate = (name) => { const validate = (name?: string | string[]) => {
if (name && !Array.isArray(name)) { if (typeof name === 'string') {
return validateField(name); return validateField(name);
} }
return props.validateFirst ? validateSeq(name) : validateAll(name); return props.validateFirst ? validateSeq(name) : validateAll(name);
}; };
const resetValidation = (name) => { const resetValidation = (name?: string | string[]) => {
if (name && !Array.isArray(name)) { if (typeof name === 'string') {
name = [name]; name = [name];
} }
@ -121,7 +136,10 @@ export default createComponent({
}); });
}; };
const scrollToField = (name, options) => { const scrollToField = (
name: string,
options?: boolean | ScrollIntoViewOptions
) => {
children.some((item) => { children.some((item) => {
if (item.name === name) { if (item.name === name) {
item.$el.scrollIntoView(options); item.$el.scrollIntoView(options);
@ -135,7 +153,7 @@ export default createComponent({
children.reduce((form, field) => { children.reduce((form, field) => {
form[field.name] = field.formValue.value; form[field.name] = field.formValue.value;
return form; return form;
}, {}); }, {} as Record<string, unknown>);
const submit = () => { const submit = () => {
const values = getValues(); const values = getValues();
@ -153,7 +171,7 @@ export default createComponent({
}); });
}; };
const onSubmit = (event) => { const onSubmit = (event: Event) => {
event.preventDefault(); event.preventDefault();
submit(); submit();
}; };

View File

@ -17,6 +17,7 @@ declare module 'vue' {
onCancel?: EventHandler; onCancel?: EventHandler;
onClosed?: EventHandler; onClosed?: EventHandler;
onChange?: EventHandler; onChange?: EventHandler;
onSubmit?: EventHandler;
onSelect?: EventHandler; onSelect?: EventHandler;
onToggle?: EventHandler; onToggle?: EventHandler;
onConfirm?: EventHandler; onConfirm?: EventHandler;