Repository: vuejs/eslint-plugin-vue
Pull request #2410 (2024-02-27 07:06:46)

fix(v-bind-style): only change kebabCase to camelCase
fix https://github.com/vuejs/eslint-plugin-vue/issues/2409




Patch:
diff --git a/lib/rules/v-bind-style.js b/lib/rules/v-bind-style.js
index 847db33a..637ded0c 100644
--- a/lib/rules/v-bind-style.js
+++ b/lib/rules/v-bind-style.js
@@ -13,6 +13,14 @@ const casing = require('../utils/casing')
  * @typedef { VDirective & { key: VBindDirectiveKey } } VBindDirective
  */
 
+/**
+ * @param {string} name
+ * @returns {string}
+ */
+function kebabCaseToCamelCase(name) {
+  return casing.isKebabCase(name) ? casing.camelCase(name) : name
+}
+
 /**
  * @param {VBindDirective} node
  * @returns {boolean}
@@ -24,11 +32,10 @@ function isSameName(node) {
     node.value?.expression?.type === 'Identifier'
       ? node.value.expression.name
       : null
-  return Boolean(
-    attrName &&
-      valueName &&
-      casing.camelCase(attrName) === casing.camelCase(valueName)
-  )
+
+  if (!attrName || !valueName) return false
+
+  return kebabCaseToCamelCase(attrName) === kebabCaseToCamelCase(valueName)
 }
 
 /**
@@ -144,7 +151,7 @@ module.exports = {
           } else if (node.key.argument.type === 'VIdentifier') {
             yield fixer.insertTextAfter(
               node,
-              `="${casing.camelCase(node.key.argument.rawName)}"`
+              `="${kebabCaseToCamelCase(node.key.argument.rawName)}"`
             )
           }
         }


Test patch:
diff --git a/tests/lib/rules/v-bind-style.js b/tests/lib/rules/v-bind-style.js
index b678bf78..f6509953 100644
--- a/tests/lib/rules/v-bind-style.js
+++ b/tests/lib/rules/v-bind-style.js
@@ -124,6 +124,12 @@ tester.run('v-bind-style', rule, {
       filename: 'test.vue',
       code: '<template><div :foo-bar/></template>',
       options: ['shorthand', { sameNameShorthand: 'always' }]
+    },
+    {
+      // https://github.com/vuejs/eslint-plugin-vue/issues/2409
+      filename: 'test.vue',
+      code: '<template><div :foo-bar="foo_bar" /></template>',
+      options: ['shorthand', { sameNameShorthand: 'always' }]
     }
   ],
   invalid: [
@@ -235,6 +241,14 @@ tester.run('v-bind-style', rule, {
       options: ['shorthand', { sameNameShorthand: 'never' }],
       errors: [unexpectedShorthand]
     },
+    {
+      // https://github.com/vuejs/eslint-plugin-vue/issues/2409
+      filename: 'test.vue',
+      code: '<template><div :foo_bar /></template>',
+      output: '<template><div :foo_bar="foo_bar" /></template>',
+      options: ['shorthand', { sameNameShorthand: 'never' }],
+      errors: [unexpectedShorthand]
+    },
     // same-name shorthand: always
     {
       filename: 'test.vue',
@@ -243,6 +257,13 @@ tester.run('v-bind-style', rule, {
       options: ['shorthand', { sameNameShorthand: 'always' }],
       errors: [expectedShorthand]
     },
+    {
+      filename: 'test.vue',
+      code: '<template><div :foo_bar="foo_bar" /></template>',
+      output: '<template><div :foo_bar /></template>',
+      options: ['shorthand', { sameNameShorthand: 'always' }],
+      errors: [expectedShorthand]
+    },
     {
       filename: 'test.vue',
       code: '<template><div v-bind:foo="foo" /></template>',