| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- import { reactive, computed, watch, toRaw, isReactive } from "vue";
- export const useFormUpdateTracker = (initialFormValue) => {
- const form = reactive(deepClone(initialFormValue));
- let originalForm = deepClone(initialFormValue);
- const updatedFields = reactive({});
- const getUpdatedFields = computed(() => {
- return updatedFields;
- });
- const hasUpdatedFields = computed(() => {
- return Object.keys(updatedFields).length > 0;
- });
- const handleNestedObjects = (obj, orig, pathArr = []) => {
- Object.keys(obj).forEach((key) => {
- const value = obj[key];
- const origValue = orig ? orig[key] : undefined;
- const currentPath = pathArr.concat(key);
- const pathStr = currentPath.join(".");
- if (Array.isArray(value)) {
- if (!isEqual(value, origValue)) {
- updatedFields[pathStr] = deepClone(value);
- } else {
- delete updatedFields[pathStr];
- }
- } else if (value && typeof value === "object" && !Array.isArray(value)) {
- handleNestedObjects(value, origValue, currentPath);
- } else {
- if (!isEqual(value, origValue)) {
- updatedFields[pathStr] = value;
- } else {
- delete updatedFields[pathStr];
- }
- }
- });
- };
- watch(
- form,
- (newValue) => {
- handleNestedObjects(newValue, originalForm);
- },
- { deep: true },
- );
- const resetUpdateForm = () => {
- Object.keys(form).forEach((key) => {
- form[key] = deepClone(originalForm[key]);
- });
- Object.keys(updatedFields).forEach((key) => {
- delete updatedFields[key];
- });
- };
- const setUpdateFormAsOriginal = () => {
- originalForm = deepClone(form);
- Object.keys(updatedFields).forEach((key) => {
- delete updatedFields[key];
- });
- };
- return {
- form,
- getUpdatedFields,
- hasUpdatedFields,
- resetUpdateForm,
- setUpdateFormAsOriginal,
- };
- };
- function deepClone(obj) {
- if (obj && isReactive(obj)) {
- obj = toRaw(obj);
- }
- if (typeof structuredClone === "function") {
- try {
- return structuredClone(obj);
- } catch (e) {
- console.warn("structuredClone not supported, using JSON methods instead");
- }
- }
- return JSON.parse(JSON.stringify(obj));
- }
- function isEqual(a, b) {
- if (a === b) return true;
- if (typeof a !== typeof b) return false;
- if (Array.isArray(a) && Array.isArray(b)) {
- if (a.length !== b.length) return false;
- return a.every((item, i) => isEqual(item, b[i]));
- }
- if (typeof a === "object" && a && b) {
- const aKeys = Object.keys(a);
- const bKeys = Object.keys(b);
- if (aKeys.length !== bKeys.length) return false;
- return aKeys.every((key) => isEqual(a[key], b[key]));
- }
- return false;
- }
|