Meituan-Dianping/mpvue · error

class="${staticClass}": Interpolation inside attributes has

Error message

class="${staticClass}": Interpolation inside attributes has been removed. Use v-bind or the colon shorthand instead. For example, instead of <div class="{{ val }}">, use <div :class="val">.

What it means

The Vue (mp platform) template compiler detected Vue 1-style mustache interpolation inside a static `class` attribute, e.g. class="{{ val }}". Attribute interpolation was removed in Vue 2; reactive classes must go through v-bind. The compiler warns and the binding simply will not work.

Source

Thrown at src/platforms/mp/compiler/modules/class.js:16

/* @flow */

import { parseText } from 'compiler/parser/text-parser'
import {
  getAndRemoveAttr,
  getBindingAttr,
  baseWarn
} from 'compiler/helpers'

function transformNode (el: ASTElement, options: CompilerOptions) {
  const warn = options.warn || baseWarn
  const staticClass = getAndRemoveAttr(el, 'class')
  if (process.env.NODE_ENV !== 'production' && staticClass) {
    const expression = parseText(staticClass, options.delimiters)
    if (expression) {
      warn(
        `class="${staticClass}": ` +
        'Interpolation inside attributes has been removed. ' +
        'Use v-bind or the colon shorthand instead. For example, ' +
        'instead of <div class="{{ val }}">, use <div :class="val">.'
      )
    }
  }
  if (staticClass) {
    el.staticClass = JSON.stringify(staticClass)
  }
  const classBinding = getBindingAttr(el, 'class', false /* getStatic */)
  if (classBinding) {
    el.classBinding = classBinding
  }
}

function genData (el: ASTElement): string {
  let data = ''

View on GitHub (pinned to 6c5d78ee04)

Solutions

  1. Bind the attribute instead: replace class="{{ val }}" with :class="val".
  2. If the value is truly static, remove the mustaches and write a plain string class.
  3. Use object/array syntax for conditional classes: :class="{ active: isActive }".

Example fix

// before
<div class="btn {{ activeClass }}">
// after
<div class="btn" :class="activeClass">
Defensive patterns

Strategy: validation

Validate before calling

function assertNoAttrInterpolation (template, attr = 'class', delims = ['{{', '}}']) {
  const re = new RegExp(attr + "\\s*=\\s*[\"'][^\"']*" + delims[0] + "[\\s\\S]*?" + delims[1])
  if (re.test(template)) throw new Error('Interpolation in ' + attr + ' attr; use :' + attr + ' instead')
}
assertNoAttrInterpolation('<div class="{{ v }}">', 'class')

Type guard

const hasAttrInterpolation = (attrVal, delims = ['{{', '}}']) =>
  typeof attrVal === 'string' && attrVal.includes(delims[0]) && attrVal.includes(delims[1]);

Prevention

When it happens

Trigger: Compiling a template element that has a plain `class` attribute whose value contains the configured text delimiters (e.g. class="{{ activeClass }}"), during transformNode in dev mode.

Common situations: Migrating a Vue 1 codebase to Vue 2; copy-pasting template examples from old tutorials; writing class="{{ 'btn ' + variant }}" by analogy with text interpolation.

Related errors


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