Meituan-Dianping/mpvue · error

<input :type="${dynamicType}" v-model="${value}">: v-model d

Error message

<input :type="${dynamicType}" v-model="${value}">:
v-model does not support dynamic input types. Use v-if branches instead.

What it means

v-model on an <input> whose `type` attribute is dynamically bound (:type or v-bind:type) cannot be compiled, because the compiler must know the input kind to generate the correct runtime model code. The compiler warns at build time in dev mode.

Source

Thrown at src/platforms/web/compiler/directives/model.js:28

// so we used some reserved tokens during compile.
export const RANGE_TOKEN = '__r'
export const CHECKBOX_RADIO_TOKEN = '__c'

export default function model (
  el: ASTElement,
  dir: ASTDirective,
  _warn: Function
): ?boolean {
  warn = _warn
  const value = dir.value
  const modifiers = dir.modifiers
  const tag = el.tag
  const type = el.attrsMap.type

  if (process.env.NODE_ENV !== 'production') {
    const dynamicType = el.attrsMap['v-bind:type'] || el.attrsMap[':type']
    if (tag === 'input' && dynamicType) {
      warn(
        `<input :type="${dynamicType}" v-model="${value}">:\n` +
        `v-model does not support dynamic input types. Use v-if branches instead.`
      )
    }
    // inputs with type="file" are read only and setting the input's
    // value will throw an error.
    if (tag === 'input' && type === 'file') {
      warn(
        `<${el.tag} v-model="${value}" type="file">:\n` +
        `File inputs are read only. Use a v-on:change listener instead.`
      )
    }
  }

  if (el.component) {
    genComponentModel(el, value, modifiers)
    // component v-model doesn't need extra runtime
    return false

View on GitHub (pinned to 6c5d78ee04)

Solutions

  1. Use v-if/v-else branches, one per concrete type, each with its own v-model.
  2. Replace v-model with :value + @input and handle types manually.
  3. Fix the type statically if it does not actually vary.

Example fix

// before
<input :type="type" v-model="value">
// after
<input v-if="type === 'text'" type="text" v-model="value">
<input v-else type="checkbox" v-model="value">
Defensive patterns

Strategy: validation

Validate before calling

function assertStaticTypeForVModel (template) {
  const inputs = template.match(/<input\b[^>]*>/g) || []
  for (const tag of inputs) {
    if (/v-model/.test(tag) && /(:type|v-bind:type)/.test(tag)) {
      throw new Error('v-model on input with dynamic :type not allowed; use v-if branches')
    }
  }
}
assertStaticTypeForVModel('<input :type="t" v-model="v">')

Prevention

When it happens

Trigger: Compiling `<input :type="inputType" v-model="value">` (or v-bind:type) in the web model compiler directive when tag is 'input' and a dynamic type binding exists.

Common situations: Reusable input components switching between text/checkbox/etc. via :type while using v-model; form builders with configurable input types.

Related errors


AI-assisted analysis of Meituan-Dianping/mpvue@6c5d78ee04 (2026-09-02). Data as JSON: /api/errors/b2126496b981abde. Report an issue: GitHub.