diff --git a/packages/compiler-sfc/__tests__/__snapshots__/cssVars.spec.ts.snap b/packages/compiler-sfc/__tests__/__snapshots__/cssVars.spec.ts.snap
index b44f584b..c290eb6f 100644
--- a/packages/compiler-sfc/__tests__/__snapshots__/cssVars.spec.ts.snap
+++ b/packages/compiler-sfc/__tests__/__snapshots__/cssVars.spec.ts.snap
@@ -74,14 +74,16 @@ export default {
expose();
_useCssVars(_ctx => ({
- \\"xxxxxxxx-_a___b____2____px__\\": ((_unref(a) + _unref(b)) / 2 + 'px' ),
+ \\"xxxxxxxx-foo\\": (_unref(foo)),
+ \\"xxxxxxxx-_a___b____2____px_\\": ((_unref(a) + _unref(b)) / 2 + 'px'),
\\"xxxxxxxx-__a___b______2___a_\\": (((_unref(a) + _unref(b))) / (2 * _unref(a)))
}))
let a = 100
let b = 200
+ let foo = 300
-return { a, b }
+return { a, b, foo }
}
}"
diff --git a/packages/compiler-sfc/__tests__/cssVars.spec.ts b/packages/compiler-sfc/__tests__/cssVars.spec.ts
index 965c9a52..f92852e8 100644
--- a/packages/compiler-sfc/__tests__/cssVars.spec.ts
+++ b/packages/compiler-sfc/__tests__/cssVars.spec.ts
@@ -204,8 +204,13 @@ describe('CSS vars injection', () => {
`\n` +
``
)
expect(content).toMatch(`_useCssVars(_ctx => ({
- "${mockId}-_a___b____2____px__": ((_unref(a) + _unref(b)) / 2 + 'px' ),
+ "${mockId}-foo": (_unref(foo)),
+ "${mockId}-_a___b____2____px_": ((_unref(a) + _unref(b)) / 2 + 'px'),
"${mockId}-__a___b______2___a_": (((_unref(a) + _unref(b))) / (2 * _unref(a)))
})`)
assertCode(content)
diff --git a/packages/compiler-sfc/src/cssVars.ts b/packages/compiler-sfc/src/cssVars.ts
index da3e164a..c7572e58 100644
--- a/packages/compiler-sfc/src/cssVars.ts
+++ b/packages/compiler-sfc/src/cssVars.ts
@@ -12,8 +12,8 @@ import { PluginCreator } from 'postcss'
import hash from 'hash-sum'
export const CSS_VARS_HELPER = `useCssVars`
-export const cssVarRE =
- /\bv-bind\s*\(\s*(?:'([^']+)'|"([^"]+)"|([^'"][^;]*))\s*\)/g
+// match v-bind() with max 2-levels of nested parens.
+const cssVarRE = /v-bind\s*\(((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*)\)/g
export function genCssVarsFromList(
vars: string[],
@@ -33,6 +33,17 @@ function genVarName(id: string, raw: string, isProd: boolean): string {
}
}
+function noramlizeExpression(exp: string) {
+ exp = exp.trim()
+ if (
+ (exp[0] === `'` && exp[exp.length - 1] === `'`) ||
+ (exp[0] === `"` && exp[exp.length - 1] === `"`)
+ ) {
+ return exp.slice(1, -1)
+ }
+ return exp
+}
+
export function parseCssVars(sfc: SFCDescriptor): string[] {
const vars: string[] = []
sfc.styles.forEach(style => {
@@ -40,7 +51,7 @@ export function parseCssVars(sfc: SFCDescriptor): string[] {
// ignore v-bind() in comments /* ... */
const content = style.content.replace(/\/\*([\s\S]*?)\*\//g, '')
while ((match = cssVarRE.exec(content))) {
- const variable = match[1] || match[2] || match[3]
+ const variable = noramlizeExpression(match[1])
if (!vars.includes(variable)) {
vars.push(variable)
}
@@ -62,8 +73,8 @@ export const cssVarsPlugin: PluginCreator = opts => {
Declaration(decl) {
// rewrite CSS variables
if (cssVarRE.test(decl.value)) {
- decl.value = decl.value.replace(cssVarRE, (_, $1, $2, $3) => {
- return `var(--${genVarName(id, $1 || $2 || $3, isProd)})`
+ decl.value = decl.value.replace(cssVarRE, (_, $1) => {
+ return `var(--${genVarName(id, noramlizeExpression($1), isProd)})`
})
}
}