v-bind-style.js 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. /**
  2. * @author Toru Nagashima
  3. * @copyright 2017 Toru Nagashima. All rights reserved.
  4. * See LICENSE file in root directory for full license.
  5. */
  6. 'use strict'
  7. const utils = require('../utils')
  8. module.exports = {
  9. meta: {
  10. type: 'suggestion',
  11. docs: {
  12. description: 'enforce `v-bind` directive style',
  13. categories: ['vue3-strongly-recommended', 'strongly-recommended'],
  14. url: 'https://eslint.vuejs.org/rules/v-bind-style.html'
  15. },
  16. fixable: 'code',
  17. schema: [{ enum: ['shorthand', 'longform'] }],
  18. messages: {
  19. expectedLonghand: "Expected 'v-bind' before ':'.",
  20. unexpectedLonghand: "Unexpected 'v-bind' before ':'.",
  21. expectedLonghandForProp: "Expected 'v-bind:' instead of '.'."
  22. }
  23. },
  24. /** @param {RuleContext} context */
  25. create(context) {
  26. const preferShorthand = context.options[0] !== 'longform'
  27. return utils.defineTemplateBodyVisitor(context, {
  28. /** @param {VDirective} node */
  29. "VAttribute[directive=true][key.name.name='bind'][key.argument!=null]"(
  30. node
  31. ) {
  32. const shorthandProp = node.key.name.rawName === '.'
  33. const shorthand = node.key.name.rawName === ':' || shorthandProp
  34. if (shorthand === preferShorthand) {
  35. return
  36. }
  37. let messageId = 'expectedLonghand'
  38. if (preferShorthand) {
  39. messageId = 'unexpectedLonghand'
  40. } else if (shorthandProp) {
  41. messageId = 'expectedLonghandForProp'
  42. }
  43. context.report({
  44. node,
  45. loc: node.loc,
  46. messageId,
  47. *fix(fixer) {
  48. if (preferShorthand) {
  49. yield fixer.remove(node.key.name)
  50. } else {
  51. yield fixer.insertTextBefore(node, 'v-bind')
  52. if (shorthandProp) {
  53. // Replace `.` by `:`.
  54. yield fixer.replaceText(node.key.name, ':')
  55. // Insert `.prop` modifier if it doesn't exist.
  56. const modifier = node.key.modifiers[0]
  57. const isAutoGeneratedPropModifier =
  58. modifier.name === 'prop' && modifier.rawName === ''
  59. if (isAutoGeneratedPropModifier) {
  60. yield fixer.insertTextBefore(modifier, '.prop')
  61. }
  62. }
  63. }
  64. }
  65. })
  66. }
  67. })
  68. }
  69. }