Repository: vuejs/vue-next
File: packages/runtime-core/src/componentEmits.ts (TypeScript)

Code before:
        }
      } else {
        const validator = emitsOptions[event]
        if (isFunction(validator)) {
          const isValid = validator(...rawArgs)
          if (!isValid) {
            warn(
              `Invalid event arguments: event validation failed for event "${event}".`,
            )
          }
        }
      }
    }
  }

  let args = rawArgs
  let isModelListener
  let modifiers
  if (
    __COMPAT__ &&
    (isModelListener = compatModelEventPrefix + event in props)
  ) {
    modifiers = props.modelModifiers
  } else if ((isModelListener = event.startsWith('update:'))) {
    modifiers = getModelModifiers(props, event.slice(7))
  }

  // for v-model update:xxx events, apply modifiers on args
  if (modifiers) {
    if (modifiers.trim) {
      args = rawArgs.map(a => (isString(a) ? a.trim() : a))
    }
    if (modifiers.number) {
      args = rawArgs.map(looseToNumber)
    }
  }

  if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) {
    devtoolsComponentEmit(instance, event, args)
  }

  if (__DEV__) {
    const lowerCaseEvent = event.toLowerCase()
    if (lowerCaseEvent !== event && props[toHandlerKey(lowerCaseEvent)]) {
      warn(
        `Event "${lowerCaseEvent}" is emitted in component ` +
          `${formatComponentName(
            instance,
            instance.type,
          )} but the handler is registered for "${event}". ` +
          `Note that HTML attributes are case-insensitive and you cannot use ` +

Review comment (suggestion):
Not a big issue, but I was wondering about the extra bytes added to the non-compat build. It's only 6 bytes, but still.

I experimented with a few ways to write this, and this version would keep the non-compat builds unchanged:

```suggestion
  const isCompatModelListener =
    __COMPAT__ && compatModelEventPrefix + event in props
  const isModelListener = isCompatModelListener || event.startsWith('update:')
  const modifiers = isCompatModelListener
    ? props.modelModifiers
    : isModelListener && getModelModifiers(props, event.slice(7))
```

Of course there are other considerations besides size.

Code after:
        }
      } else {
        const validator = emitsOptions[event]
        if (isFunction(validator)) {
          const isValid = validator(...rawArgs)
          if (!isValid) {
            warn(
              `Invalid event arguments: event validation failed for event "${event}".`,
            )
          }
        }
      }
    }
  }

  let args = rawArgs
  const isCompatModelListener =
    __COMPAT__ && compatModelEventPrefix + event in props
  const isModelListener = isCompatModelListener || event.startsWith('update:')
  const modifiers = isCompatModelListener
    ? props.modelModifiers
    : isModelListener && getModelModifiers(props, event.slice(7))

  // for v-model update:xxx events, apply modifiers on args
  if (modifiers) {
    if (modifiers.trim) {
      args = rawArgs.map(a => (isString(a) ? a.trim() : a))
    }
    if (modifiers.number) {
      args = rawArgs.map(looseToNumber)
    }
  }

  if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) {
    devtoolsComponentEmit(instance, event, args)
  }

  if (__DEV__) {
    const lowerCaseEvent = event.toLowerCase()
    if (lowerCaseEvent !== event && props[toHandlerKey(lowerCaseEvent)]) {
      warn(
        `Event "${lowerCaseEvent}" is emitted in component ` +
          `${formatComponentName(
            instance,
            instance.type,
          )} but the handler is registered for "${event}". ` +
          `Note that HTML attributes are case-insensitive and you cannot use ` +
          `v-on to listen to camelCase events when using in-DOM templates. ` +
          `You should probably use "${hyphenate(
            event,
          )}" instead of "${event}".`,