基于vue3.0和element-plus的组件库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

53 lines
1.4 KiB

import { isReactive, isReadonly, isRef, toRaw, unref } from "vue";
export const CIRCULAR_REFERENCE_TEXT = "[Circular]";
export interface CircularReferenceMarker {
__jsonViewCircular: true;
path?: string;
}
export function createCircularReferenceMarker(path?: string): CircularReferenceMarker {
return {
__jsonViewCircular: true,
path,
};
}
export function isCircularReferenceMarker(value: unknown): value is CircularReferenceMarker {
return Boolean(
value &&
typeof value === "object" &&
"__jsonViewCircular" in value &&
(value as { __jsonViewCircular?: boolean }).__jsonViewCircular
);
}
export function formatCircularReference(path?: string) {
return path ? `[Circular: ${path}]` : CIRCULAR_REFERENCE_TEXT;
}
export function normalizeVueValue(
value: unknown,
currentPath?: string,
seenRefs = new WeakMap<object, string | undefined>()
): unknown {
let current = value;
while (isRef(current)) {
const reference = current as object;
const existingPath = seenRefs.get(reference);
if (existingPath !== undefined || seenRefs.has(reference)) {
return createCircularReferenceMarker(existingPath ?? currentPath);
}
seenRefs.set(reference, currentPath);
current = unref(current);
}
if (current !== null && typeof current === "object" && (isReactive(current) || isReadonly(current))) {
return toRaw(current);
}
return current;
}