parent
2f4e8d34ed
commit
4c4996fb72
|
@ -76,7 +76,7 @@ export default {
|
|||
$formValue: {
|
||||
immediate: false,
|
||||
handler(newValue) {
|
||||
if (this.$formName !== undefined && this.$pcForm?.states?.[this.$formName] && newValue !== this.d_value) {
|
||||
if (this.$pcForm?.states?.[this.$formName] && newValue !== this.d_value) {
|
||||
this.d_value = newValue;
|
||||
}
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ export default {
|
|||
return this.d_value ?? this.$pcFormField?.initialValue ?? this.$pcForm?.initialValues?.[this.$formName];
|
||||
},
|
||||
$formValue() {
|
||||
return this.$pcForm?.states?.[this.$formName]?.value;
|
||||
return this.$pcFormField?.$field?.value ?? this.$pcForm?.states?.[this.$formName]?.value;
|
||||
},
|
||||
controlled() {
|
||||
return this.$inProps.hasOwnProperty('modelValue') || (!this.$inProps.hasOwnProperty('modelValue') && !this.$inProps.hasOwnProperty('defaultValue'));
|
||||
|
|
|
@ -107,6 +107,16 @@ export interface FormSubmitEvent {
|
|||
reset: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset events
|
||||
*/
|
||||
export interface FormResetEvent {
|
||||
/**
|
||||
* The original DOM event.
|
||||
*/
|
||||
originalEvent: Event;
|
||||
}
|
||||
|
||||
/**
|
||||
* The state of a form field.
|
||||
*/
|
||||
|
@ -247,6 +257,11 @@ export interface FormEmitsOptions {
|
|||
* @param {FormSubmitEvent} event - Custom submit event.
|
||||
*/
|
||||
submit: (event: FormSubmitEvent) => void;
|
||||
/**
|
||||
* Emitted when the form is reset.
|
||||
* @param {FormResetEvent} event - Custom reset event.
|
||||
*/
|
||||
reset: (event: FormResetEvent) => void;
|
||||
}
|
||||
|
||||
export declare type FormEmits = EmitFn<FormEmitsOptions>;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<form @submit.prevent="onSubmit" :class="cx('root')" v-bind="ptmi('root')">
|
||||
<form @submit.prevent="onSubmit" @reset.prevent="onReset" :class="cx('root')" v-bind="ptmi('root')">
|
||||
<slot :register :valid :reset v-bind="states" />
|
||||
</form>
|
||||
</template>
|
||||
|
@ -13,7 +13,7 @@ export default {
|
|||
name: 'Form',
|
||||
extends: BaseForm,
|
||||
inheritAttrs: false,
|
||||
emits: ['submit'],
|
||||
emits: ['submit', 'reset'],
|
||||
setup(props, { emit }) {
|
||||
const $form = useForm(props);
|
||||
|
||||
|
@ -27,10 +27,15 @@ export default {
|
|||
emit('submit', e);
|
||||
});
|
||||
|
||||
const onReset = $form.handleReset((e) => {
|
||||
emit('reset', e);
|
||||
});
|
||||
|
||||
return {
|
||||
register,
|
||||
onSubmit,
|
||||
...omit($form, ['handleSubmit'])
|
||||
onReset,
|
||||
...omit($form, ['handleSubmit', 'handleReset'])
|
||||
};
|
||||
}
|
||||
};
|
||||
|
|
|
@ -11,8 +11,11 @@ export interface useFormFieldState {
|
|||
|
||||
export interface useFormReturn {
|
||||
defineField: (field: string, options?: any) => any;
|
||||
setFieldValue: (field: string, value: any) => void;
|
||||
handleSubmit: (event: any) => any;
|
||||
handleReset: (event: any) => any;
|
||||
validate: (field: string) => any;
|
||||
setValues: (values: Record<string, any>) => void;
|
||||
reset: () => void;
|
||||
valid: boolean;
|
||||
states: Record<string, useFormFieldState>;
|
||||
|
|
|
@ -7,6 +7,29 @@ function tryOnMounted(fn, sync = true) {
|
|||
else nextTick(fn);
|
||||
}
|
||||
|
||||
function watchPausable(source, callback, options) {
|
||||
const isActive = ref(true);
|
||||
|
||||
const stop = watch(
|
||||
source,
|
||||
(newValue, oldValue) => {
|
||||
if (!isActive.value) return;
|
||||
callback(newValue, oldValue);
|
||||
},
|
||||
options
|
||||
);
|
||||
|
||||
return {
|
||||
stop,
|
||||
pause: () => {
|
||||
isActive.value = false;
|
||||
},
|
||||
resume: () => {
|
||||
isActive.value = true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export const useForm = (options = {}) => {
|
||||
const states = reactive({});
|
||||
const fields = reactive({});
|
||||
|
@ -47,6 +70,8 @@ export const useForm = (options = {}) => {
|
|||
};
|
||||
|
||||
const defineField = (field, fieldOptions) => {
|
||||
fields[field]?._watcher.stop();
|
||||
|
||||
states[field] ||= getInitialState(field, fieldOptions?.initialValue);
|
||||
|
||||
const props = mergeProps(resolve(fieldOptions, states[field])?.props, resolve(fieldOptions?.props, states[field]), {
|
||||
|
@ -68,9 +93,7 @@ export const useForm = (options = {}) => {
|
|||
}
|
||||
});
|
||||
|
||||
fields[field] = { props, states: states[field], options: fieldOptions };
|
||||
|
||||
watch(
|
||||
const _watcher = watchPausable(
|
||||
() => states[field].value,
|
||||
(newValue, oldValue) => {
|
||||
if (states[field].pristine) {
|
||||
|
@ -85,6 +108,8 @@ export const useForm = (options = {}) => {
|
|||
}
|
||||
);
|
||||
|
||||
fields[field] = { props, states: states[field], options: fieldOptions, _watcher };
|
||||
|
||||
return [states[field], props];
|
||||
};
|
||||
|
||||
|
@ -102,6 +127,16 @@ export const useForm = (options = {}) => {
|
|||
};
|
||||
};
|
||||
|
||||
const handleReset = (callback) => {
|
||||
return async (event) => {
|
||||
reset();
|
||||
|
||||
return callback({
|
||||
originalEvent: event
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
const validate = async (field) => {
|
||||
const resolverOptions = Object.entries(states).reduce(
|
||||
(acc, [key, val]) => {
|
||||
|
@ -147,7 +182,22 @@ export const useForm = (options = {}) => {
|
|||
};
|
||||
|
||||
const reset = () => {
|
||||
Object.keys(states).forEach((field) => (fields[field].states = states[field] = getInitialState(field, fields[field]?.options?.initialValue)));
|
||||
Object.keys(states).forEach(async (field) => {
|
||||
const watcher = fields[field]._watcher;
|
||||
|
||||
watcher.pause();
|
||||
fields[field].states = states[field] = getInitialState(field, fields[field]?.options?.initialValue);
|
||||
await nextTick();
|
||||
watcher.resume();
|
||||
});
|
||||
};
|
||||
|
||||
const setFieldValue = (field, value) => {
|
||||
states[field].value = value;
|
||||
};
|
||||
|
||||
const setValues = (values) => {
|
||||
Object.keys(values).forEach((field) => setFieldValue(field, values[field]));
|
||||
};
|
||||
|
||||
const validateOnMounted = () => {
|
||||
|
@ -158,8 +208,11 @@ export const useForm = (options = {}) => {
|
|||
|
||||
return {
|
||||
defineField,
|
||||
setFieldValue,
|
||||
handleSubmit,
|
||||
handleReset,
|
||||
validate,
|
||||
setValues,
|
||||
reset,
|
||||
valid,
|
||||
states,
|
||||
|
|
Loading…
Reference in New Issue