|
@@ -12,7 +12,7 @@
|
|
|
* @description 用于RuleForm的配置
|
|
* @description 用于RuleForm的配置
|
|
|
* @author Chauncey
|
|
* @author Chauncey
|
|
|
*/
|
|
*/
|
|
|
-import { ref, reactive, watch, onUnmounted } from 'vue';
|
|
|
|
|
|
|
+import { ref, reactive } from 'vue';
|
|
|
import type { FormRules } from 'element-plus';
|
|
import type { FormRules } from 'element-plus';
|
|
|
import { cloneDeep, isEqual } from 'lodash-es';
|
|
import { cloneDeep, isEqual } from 'lodash-es';
|
|
|
import { onBeforeRouteLeave } from 'vue-router';
|
|
import { onBeforeRouteLeave } from 'vue-router';
|
|
@@ -26,78 +26,18 @@ export const useFormConfigHook = <T extends Record<string, any> = Record<string,
|
|
|
) => {
|
|
) => {
|
|
|
const ruleFormConfig = ref<FormConfig[]>(config);
|
|
const ruleFormConfig = ref<FormConfig[]>(config);
|
|
|
const ruleFormData = reactive<T>(cloneDeep(data));
|
|
const ruleFormData = reactive<T>(cloneDeep(data));
|
|
|
- const initRuleFormData = ref<T>(cloneDeep(data));
|
|
|
|
|
|
|
+ const initRuleFormData = ref<T>();
|
|
|
const formRules = reactive<FormRules<T>>(rules || {});
|
|
const formRules = reactive<FormRules<T>>(rules || {});
|
|
|
- const routeLeaveGuardRegistered = ref(false);
|
|
|
|
|
- let stopAutoSyncWatch: (() => void) | null = null;
|
|
|
|
|
- let autoSyncTimer: ReturnType<typeof setTimeout> | null = null;
|
|
|
|
|
- let removeInteractionListeners: (() => void) | null = null;
|
|
|
|
|
-
|
|
|
|
|
- const stopAutoSyncBaseline = () => {
|
|
|
|
|
- if (stopAutoSyncWatch) {
|
|
|
|
|
- stopAutoSyncWatch();
|
|
|
|
|
- stopAutoSyncWatch = null;
|
|
|
|
|
- }
|
|
|
|
|
- if (autoSyncTimer) {
|
|
|
|
|
- clearTimeout(autoSyncTimer);
|
|
|
|
|
- autoSyncTimer = null;
|
|
|
|
|
- }
|
|
|
|
|
- if (removeInteractionListeners) {
|
|
|
|
|
- removeInteractionListeners();
|
|
|
|
|
- removeInteractionListeners = null;
|
|
|
|
|
- }
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- const startAutoSyncBaseline = () => {
|
|
|
|
|
- stopAutoSyncBaseline();
|
|
|
|
|
-
|
|
|
|
|
- stopAutoSyncWatch = watch(
|
|
|
|
|
- () => ruleFormData,
|
|
|
|
|
- () => {
|
|
|
|
|
- initRuleFormData.value = cloneDeep(ruleFormData as T);
|
|
|
|
|
- },
|
|
|
|
|
- { deep: true, flush: 'post' },
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- const stopByUserInteraction = () => {
|
|
|
|
|
- stopAutoSyncBaseline();
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- if (typeof window !== 'undefined') {
|
|
|
|
|
- const events: Array<keyof WindowEventMap> = ['input', 'change', 'keydown', 'compositionend'];
|
|
|
|
|
- events.forEach((eventName) => {
|
|
|
|
|
- window.addEventListener(eventName, stopByUserInteraction, true);
|
|
|
|
|
- });
|
|
|
|
|
- removeInteractionListeners = () => {
|
|
|
|
|
- events.forEach((eventName) => {
|
|
|
|
|
- window.removeEventListener(eventName, stopByUserInteraction, true);
|
|
|
|
|
- });
|
|
|
|
|
- };
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- autoSyncTimer = setTimeout(() => {
|
|
|
|
|
- stopAutoSyncBaseline();
|
|
|
|
|
- }, 1500);
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
const cloneRuleFormData = () => {
|
|
const cloneRuleFormData = () => {
|
|
|
- if (routeLeaveGuardRegistered.value) return;
|
|
|
|
|
initRuleFormData.value = cloneDeep(ruleFormData as T);
|
|
initRuleFormData.value = cloneDeep(ruleFormData as T);
|
|
|
};
|
|
};
|
|
|
-
|
|
|
|
|
const hasFormChanged = () => {
|
|
const hasFormChanged = () => {
|
|
|
- return !isEqual(initRuleFormData.value, ruleFormData);
|
|
|
|
|
|
|
+ return isEqual(initRuleFormData.value, ruleFormData);
|
|
|
};
|
|
};
|
|
|
-
|
|
|
|
|
const beforeRouteLeave = () => {
|
|
const beforeRouteLeave = () => {
|
|
|
- if (routeLeaveGuardRegistered.value) return;
|
|
|
|
|
- initRuleFormData.value = cloneDeep(ruleFormData as T);
|
|
|
|
|
- routeLeaveGuardRegistered.value = true;
|
|
|
|
|
- startAutoSyncBaseline();
|
|
|
|
|
-
|
|
|
|
|
onBeforeRouteLeave((to, from, next) => {
|
|
onBeforeRouteLeave((to, from, next) => {
|
|
|
const hasChange = hasFormChanged();
|
|
const hasChange = hasFormChanged();
|
|
|
- if (!hasChange) {
|
|
|
|
|
|
|
+ if (hasChange) {
|
|
|
next();
|
|
next();
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
@@ -116,11 +56,6 @@ export const useFormConfigHook = <T extends Record<string, any> = Record<string,
|
|
|
}, 200);
|
|
}, 200);
|
|
|
});
|
|
});
|
|
|
};
|
|
};
|
|
|
-
|
|
|
|
|
- onUnmounted(() => {
|
|
|
|
|
- stopAutoSyncBaseline();
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
return {
|
|
return {
|
|
|
ruleFormConfig,
|
|
ruleFormConfig,
|
|
|
ruleFormData,
|
|
ruleFormData,
|
|
@@ -128,4 +63,4 @@ export const useFormConfigHook = <T extends Record<string, any> = Record<string,
|
|
|
cloneRuleFormData,
|
|
cloneRuleFormData,
|
|
|
beforeRouteLeave,
|
|
beforeRouteLeave,
|
|
|
};
|
|
};
|
|
|
-};
|
|
|
|
|
|
|
+};
|