import { computed, reactive, ref, Ref, watchEffect } from "vue"; import { PropertyDescribes } from "../html-mount/propertys"; import { installGlobalVar } from "./use-global-vars"; import { inRevise, mergeFuns } from "@/utils/shared"; export const useGlobalDescribes = installGlobalVar(() => { const shapesDescribes: Record = reactive({}); const shapesSetCount: Record = {}; const data: Record = reactive({}); return { set(item: { id: string }, descs: PropertyDescribes) { if (item.id in shapesSetCount) { shapesSetCount[item.id]++ } else { shapesSetCount[item.id] = 1 } shapesDescribes[item.id] = descs; data[item.id] = item; }, del(id: string) { if (id in shapesSetCount) { shapesSetCount[id]-- } if (shapesSetCount[id] === 0) { delete shapesDescribes[id]; delete shapesSetCount[id] delete data[id] } }, get(id: string) { return ( shapesDescribes[id] && { desc: shapesDescribes[id], data: data[id] } ); }, }; }); export const useComponentsDescribes = (ids: Ref) => { const gdesc = useGlobalDescribes(); const excludeKeys = ["length", "name"]; const groups = computed(() => { return ids.value.map((id) => gdesc.get(id)).filter((item) => !!item); }); const shareDescribes = computed(() => { if (groups.value.length === 0) { return {}; } const shareDescribes: Record< string, { desc: PropertyDescribes[string][]; data: { id: string }[] } > = {}; const shareKeys: string[] = Object.keys(groups.value[0].desc); for (const item of groups.value) { const keys = Object.keys(item.desc); for (const key of keys) { if (shareKeys.includes(key)) { if (!shareDescribes[key]) { shareDescribes[key] = { desc: [], data: [] }; } else { const temp = shareDescribes[key].desc[0]; if (inRevise(temp.props, item.desc[key].props)) { delete shareDescribes[key]; shareKeys.splice(shareKeys.indexOf(key), 1); continue; } } shareDescribes[key].desc.push(item.desc[key]); shareDescribes[key].data.push(item.data); } } for (let i = 0; i < shareKeys.length; i++) { if (!keys.includes(shareKeys[i])) { delete shareDescribes[shareKeys[i]]; shareKeys.splice(i--, 1); } } } return shareDescribes; }); const stopWatchs: (() => void)[] = [] const mergeDesc = computed(() => { mergeFuns(stopWatchs)() stopWatchs.length = 0 const mergeDesc: Record< string, PropertyDescribes[string] & { joins: { id: string }[] } > = {}; for (const key in shareDescribes.value) { if (excludeKeys.includes(key)) continue; const { desc: descs, data } = shareDescribes.value[key]; mergeDesc[key] = { ...descs[0], joins: data, }; let value = descs[0].value; let i = 1; for (; i < descs.length; i++) { if (descs[i].value !== value) { break; } } if (i !== descs.length) { mergeDesc[key].label = mergeDesc[key].label + '(多值)' value = undefined } Object.defineProperty(mergeDesc[key], "value", { get() { return value }, set(val) { for (const desc of descs) { desc.value = val; } return true; }, }); delete mergeDesc[key].default; } return mergeDesc; }); return mergeDesc; };