Skip to content

Commit

Permalink
fix(form): formitem 的值如果是对象会自动重置为空对象
Browse files Browse the repository at this point in the history
  • Loading branch information
oasis-cloud committed Jan 20, 2025
1 parent 16fb6e5 commit 31fab59
Showing 1 changed file with 83 additions and 23 deletions.
106 changes: 83 additions & 23 deletions src/utils/merge.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,89 @@
export function merge(...objects: any[]) {
const result: any = Array.isArray(objects[0]) ? [] : {}

function mergeHelper(obj: any, path: string[] = []) {
for (const [key, value] of Object.entries(obj)) {
const newPath = [...path, key]

if (Array.isArray(value)) {
// Arrays are always overridden
result[key] = [...value]
} else if (typeof value === 'object' && value !== null) {
// Check for circular references
export default main

export function main(clone: boolean, ...items: any[]): any
export function main(...items: any[]): any
export function main(...items: any[]) {
return merge(...items)
}

main.clone = clone
main.isPlainObject = isPlainObject
main.recursive = recursive

export function merge(clone: boolean, ...items: any[]): any
export function merge(...items: any[]): any
export function merge(...items: any[]) {
return _merge(items[0] === true, false, items)
}

export function recursive(clone: boolean, ...items: any[]): any
export function recursive(...items: any[]): any
export function recursive(...items: any[]) {
return _merge(items[0] === true, true, items)
}

export function clone<T>(input: T): T {
if (Array.isArray(input)) {
const output = []

for (let index = 0; index < input.length; ++index)
output.push(clone(input[index]))

return output as any
}
if (isPlainObject(input)) {
const output: any = {}

// eslint-disable-next-line guard-for-in
for (const index in input) output[index] = clone((input as any)[index])

return output as any
}
return input
}

export function isPlainObject(input: unknown): input is NonNullable<any> {
if (input === null || typeof input !== 'object') return false
if (Object.getPrototypeOf(input) === null) return true
let ref = input
while (Object.getPrototypeOf(ref) !== null) ref = Object.getPrototypeOf(ref)
return Object.getPrototypeOf(input) === ref
}

function _recursiveMerge(base: any, extend: any) {
if (!isPlainObject(base) || !isPlainObject(extend)) return extend
for (const key in extend) {
if (key === '__proto__' || key === 'constructor' || key === 'prototype')
// eslint-disable-next-line no-continue
continue
base[key] =
isPlainObject(base[key]) && isPlainObject(extend[key])
? _recursiveMerge(base[key], extend[key])
: extend[key]
}

return base
}

function _merge(isClone: boolean, isRecursive: boolean, items: any[]) {
let result

if (isClone || !isPlainObject((result = items.shift()))) result = {}

for (let index = 0; index < items.length; ++index) {
const item = items[index]

// eslint-disable-next-line no-continue
if (!isPlainObject(item)) continue

for (const key in item) {
if (key === '__proto__' || key === 'constructor' || key === 'prototype')
// eslint-disable-next-line no-continue
if (path.some((p: any) => p === value)) continue

// Recursively merge objects
if (!result[key]) result[key] = {}
mergeHelper(value, newPath)
} else {
// Set primitive values
result[key] = value
}
continue
const value = isClone ? clone(item[key]) : item[key]
result[key] = isRecursive ? _recursiveMerge(result[key], value) : value
}
}

objects.filter((obj) => !!obj).forEach((obj) => mergeHelper(obj))

return result
}

0 comments on commit 31fab59

Please sign in to comment.