sard-uniapp
Version:
sard-uniapp 是一套基于 Uniapp + Vue3 框架开发的兼容多端的 UI 组件库
99 lines (98 loc) • 3.52 kB
JavaScript
import { markRaw, provide, reactive, toRef, watch } from 'vue';
import { arrayEqual, noop, toArray } from '../../utils';
import { formContextSymbol, } from './common';
import { Validator } from './Validator';
import { useTranslate } from '../locale';
export function useForm(props) {
const getMatchedField = (name) => {
return fields.find((field) => {
return arrayEqual(toArray(field.name), toArray(name));
});
};
const getMatchedFields = (nameList) => {
let matchedFields = fields;
if (nameList && nameList.length > 0) {
matchedFields = fields.filter((field) => {
return (nameList.findIndex((name) => arrayEqual(toArray(field.name), toArray(name))) > -1);
});
}
return matchedFields;
};
const validate = async (nameList) => {
const settledResult = await Promise.allSettled(getMatchedFields(nameList).map((field) => {
return field.validate();
}));
const rejectedResult = settledResult.filter((result) => {
return result.status === 'rejected';
});
if (rejectedResult.length > 0) {
const errors = rejectedResult.map((result) => {
return result.reason;
});
if (props.scrollToFirstError) {
scrollToField(errors[0].name);
}
throw errors;
}
};
const reset = async (nameList) => {
await Promise.allSettled(getMatchedFields(nameList).map((field) => {
field.reset();
}));
};
const clearValidate = async (nameList) => {
await Promise.allSettled(getMatchedFields(nameList).map((field) => {
field.clearValidate();
}));
};
const scrollToField = (name) => {
getMatchedField(name)?.scrollToField();
};
const fields = [];
const addField = (formItemContext) => {
fields.push(formItemContext);
};
const removeField = (formItemContext) => {
const index = fields.indexOf(formItemContext);
if (index !== -1) {
fields.splice(index, 1);
}
};
const validator = markRaw(new Validator());
const { select } = useTranslate('form.defaultValidateMessages');
validator.setValidateMessages(select());
watch(() => props.rules, () => {
if (props.validateOnRuleChange) {
validate().catch(noop);
}
}, { deep: true, flush: 'post' });
provide(formContextSymbol, reactive({
model: toRef(() => props.model),
rules: toRef(() => props.rules),
validateTrigger: toRef(() => props.validateTrigger),
direction: toRef(() => props.direction),
labelWidth: toRef(() => props.labelWidth),
labelAlign: toRef(() => props.labelAlign),
labelValign: toRef(() => props.labelValign),
starPosition: toRef(() => props.starPosition),
contentPosition: toRef(() => props.contentPosition),
hideStar: toRef(() => props.hideStar),
showError: toRef(() => props.showError),
scrollIntoViewOptions: toRef(() => props.scrollIntoViewOptions),
disabled: toRef(() => props.disabled),
readonly: toRef(() => props.readonly),
scrollDuration: toRef(() => props.scrollDuration),
addField,
removeField,
validator,
}));
const expose = {
validate,
reset,
clearValidate,
scrollToField,
};
return {
expose,
};
}