SoFunction
Updated on 2025-03-04

Detailed explanation of the usage of Vue mergeProps

Many people don’t know the usage of megreProps. Today we will explain the usage and principles of mergeProps.

usage

Which of the following usages do you think is correct?

so

style: mergeProps({
    width: 
}, )

Or so

style: mergeProps({
    style: {
        width: 
    },
    ...(xProps?.style ?? {})
})

Still so

style: mergeProps(
    {
      style: { width:  },
    },
    xProps,
).style

Which of the above would you use if you use it?

have no idea

Because I wrote jsx syntax, I checked itjsx syntax for vue3, I found that there was no explanation for this, I only said that it was enabled by default

So govue3 official websiteFind, find

megreProps:Merge multiple props objects with special handling for certain props.

It means combining multiple prop objects and special processing of certain props.

So the previous two writing methods are wrong

Then I looked at the way to write mergeProps source code

// ...args collects multiple objects into an arrayexport function mergeProps(...args: (Data & VNodeProps)[]) {
  //The final merger result  const ret: Data = {}
  //Transfer through multiple objects passed by the user  for (let i = 0; i < ; i++) {
    // Get the passed object value    const toMerge = args[i]
    for (const key in toMerge) {
       //Serialization and merging of the class      if (key === 'class') {
        if ( !== ) {
           = normalizeClass([, ])
        }
      //Serialization and merging of style      } else if (key === 'style') {
         = normalizeStyle([, ])
      // Merge other bound properties      } else if (isOn(key)) {
        const existing = ret[key]
        const incoming = toMerge[key]
        if (
          incoming &&
          existing !== incoming &&
          !(isArray(existing) && (incoming))
        ) {
          ret[key] = existing
            ? [].concat(existing as any, incoming as any)
            : incoming
        }
      // If it is a user-defined attribute on a normal element, then directly assign the value      } else if (key !== '') {
        ret[key] = toMerge[key]
      }
    }
  }
  return ret
}

So the object you pass in needs to have style, class and other keys

Next, take a look at the normalizeClass method. This method is to serialize the class of various formats written by the user (such as arrays, objects, and strings) into strings and give them to the final rendered elements.

export function normalizeClass(value: unknown): string {
  let res = ''
  // If it is a string, return it directly  if (isString(value)) {
    res = value
  // If it is an array  } else if (isArray(value)) {
    for (let i = 0; i < ; i++) {
      // Recursive calls are processed      const normalized = normalizeClass(value[i])
      if (normalized) {
        res += normalized + ' '
      }
    }
  // If it is an object, such as { active: isActive, 'text-danger': hasError }, the key needs to be spliced  } else if (isObject(value)) {
    for (const name in value) {
      if (value[name]) {
        res += name + ' '
      }
    }
  }
  return ()
}

Let's take a look at the normalizeStyle function

export type NormalizedStyle = Record<string, string | number>
export function normalizeStyle(
  value: unknown
): NormalizedStyle | string | undefined {
  // If it's an array  if (isArray(value)) {
    const res: NormalizedStyle = {}
    for (let i = 0; i < ; i++) {
      const item = value[i]
      const normalized = isString(item)
        ? parseStringStyle(item)
        : (normalizeStyle(item) as NormalizedStyle)
      if (normalized) {
        //Save the serialized style to ret        for (const key in normalized) {
          res[key] = normalized[key]
        }
      }
    }
    return res
  } else if (isString(value)) {
    return value
  } else if (isObject(value)) {
    return value
  }
}

parseStringStyle function is to split the string pairs and then set the corresponding key and value

The style on the element can only use string, so stringifyStyle is required when it is finally hung on the dom element.

export function stringifyStyle(
  styles: NormalizedStyle | string | undefined
): string {
  let ret = ''
  if (!styles || isString(styles)) {
    return ret
  }
  for (const key in styles) {
    const value = styles[key]
    const normalizedKey = (`--`) ? key : hyphenate(key)
    if (
      isString(value) ||
      (typeof value === 'number' && isNoUnitNumericStyleProp(normalizedKey))
    ) {
      // only render valid values
      ret += `${normalizedKey}:${value};`
    }
  }
  return ret
}

Therefore, by simply analyzing the mergeProps code of vue3, you can know its principle, and you will be more proficient in using it

This is the end of this article about the detailed explanation of the usage of Vue mergeProps. For more related content of Vue mergeProps, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!