refactor(Form): refactor with composition api

This commit is contained in:
chenjiahan 2020-09-21 16:58:44 +08:00
parent 00dbf2cc50
commit 92aac941fc
2 changed files with 63 additions and 76 deletions

View File

@ -230,7 +230,7 @@ export default createComponent({
const validateWithTrigger = (trigger) => { const validateWithTrigger = (trigger) => {
if (form && props.rules) { if (form && props.rules) {
const defaultTrigger = form.validateTrigger === trigger; const defaultTrigger = form.props.validateTrigger === trigger;
const rules = props.rules.filter((rule) => { const rules = props.rules.filter((rule) => {
if (rule.trigger) { if (rule.trigger) {
return rule.trigger === trigger; return rule.trigger === trigger;
@ -329,7 +329,7 @@ export default createComponent({
if (typeof props.error === 'boolean') { if (typeof props.error === 'boolean') {
return props.error; return props.error;
} }
if (form && form.showError && state.validateFailed) { if (form && form.props.showError && state.validateFailed) {
return true; return true;
} }
}); });
@ -339,8 +339,8 @@ export default createComponent({
return props[key]; return props[key];
} }
if (form && isDef(form[key])) { if (form && isDef(form.props[key])) {
return form[key]; return form.props[key];
} }
}; };
@ -508,7 +508,7 @@ export default createComponent({
}; };
const renderMessage = () => { const renderMessage = () => {
if (form && form.showErrorMessage === false) { if (form && form.props.showErrorMessage === false) {
return; return;
} }

View File

@ -1,4 +1,6 @@
import { provide, reactive } from 'vue';
import { createNamespace } from '../utils'; import { createNamespace } from '../utils';
import { useExpose } from '../composition/use-expose';
const [createComponent, bem] = createNamespace('form'); const [createComponent, bem] = createNamespace('form');
@ -33,24 +35,16 @@ export default createComponent({
emits: ['submit', 'failed'], emits: ['submit', 'failed'],
provide() { setup(props, { emit, slots }) {
return { const children = reactive([]);
[FORM_KEY]: this,
};
},
data() { provide(FORM_KEY, { props, children });
return {
children: [],
};
},
methods: { const validateSeq = () =>
validateSeq() { new Promise((resolve, reject) => {
return new Promise((resolve, reject) => {
const errors = []; const errors = [];
this.children children
.reduce( .reduce(
(promise, field) => (promise, field) =>
promise.then(() => { promise.then(() => {
@ -72,12 +66,10 @@ export default createComponent({
} }
}); });
}); });
},
validateAll() { const validateAll = () =>
return new Promise((resolve, reject) => { new Promise((resolve, reject) => {
Promise.all(this.children.map((item) => item.validate())).then( Promise.all(children.map((item) => item.validate())).then((errors) => {
(errors) => {
errors = errors.filter((item) => item); errors = errors.filter((item) => item);
if (errors.length) { if (errors.length) {
@ -85,21 +77,11 @@ export default createComponent({
} else { } else {
resolve(); resolve();
} }
}
);
}); });
}, });
// @exposed-api const validateField = (name) => {
validate(name) { const matched = children.filter((item) => item.props.name === name);
if (name) {
return this.validateField(name);
}
return this.validateFirst ? this.validateSeq() : this.validateAll();
},
validateField(name) {
const matched = this.children.filter((item) => item.props.name === name);
if (matched.length) { if (matched.length) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -114,65 +96,70 @@ export default createComponent({
} }
return Promise.reject(); return Promise.reject();
}, };
// @exposed-api const validate = (name) => {
resetValidation(name) { if (name) {
this.children.forEach((item) => { return validateField(name);
}
return props.validateFirst ? validateSeq() : validateAll();
};
const resetValidation = (name) => {
children.forEach((item) => {
if (!name || item.props.name === name) { if (!name || item.props.name === name) {
item.resetValidation(); item.resetValidation();
} }
}); });
}, };
// @exposed-api const scrollToField = (name, options) => {
scrollToField(name, options) { children.some((item) => {
this.children.some((item) => {
if (item.props.name === name) { if (item.props.name === name) {
item.root.value.scrollIntoView(options); item.root.value.scrollIntoView(options);
return true; return true;
} }
return false; return false;
}); });
}, };
getValues() { const getValues = () =>
return this.children.reduce((form, field) => { children.reduce((form, field) => {
form[field.props.name] = field.formValue; form[field.props.name] = field.formValue;
return form; return form;
}, {}); }, {});
},
onSubmit(event) { const submit = () => {
event.preventDefault(); const values = getValues();
this.submit();
},
// @exposed-api validate()
submit() {
const values = this.getValues();
this.validate()
.then(() => { .then(() => {
this.$emit('submit', values); emit('submit', values);
}) })
.catch((errors) => { .catch((errors) => {
this.$emit('failed', { emit('failed', { values, errors });
values,
errors,
});
if (this.scrollToError) { if (props.scrollToError) {
this.scrollToField(errors[0].name); scrollToField(errors[0].name);
} }
}); });
}, };
},
render() { const onSubmit = (event) => {
return ( event.preventDefault();
<form class={bem()} onSubmit={this.onSubmit}> submit();
{this.$slots.default?.()} };
useExpose({
submit,
validate,
scrollToField,
resetValidation,
});
return () => (
<form class={bem()} onSubmit={onSubmit}>
{slots.default?.()}
</form> </form>
); );
}, },