diff --git a/docs/rules/v-on-handler-style.md b/docs/rules/v-on-handler-style.md index 039577494..4fd1d3dae 100644 --- a/docs/rules/v-on-handler-style.md +++ b/docs/rules/v-on-handler-style.md @@ -47,7 +47,7 @@ This rule aims to enforce a consistent style in `v-on` event handlers: ```json { "vue/v-on-handler-style": ["error", - ["method", "inline-function"], // ["method", "inline-function"] | ["method", "inline"] | "inline-function" | "inline" + ["method", "inline-function"], // ["method", "inline-function"] | ["method", "inline"] | ["inline", "inline-function"] | "inline-function" | "inline" { "ignoreIncludesComment": false } @@ -58,10 +58,12 @@ This rule aims to enforce a consistent style in `v-on` event handlers: - First option ... Specifies the name of an allowed style. Default is `["method", "inline-function"]`. - `["method", "inline-function"]` ... Allow handlers by method binding. e.g. `v-on:click="handler"`. Allow inline functions where method handlers cannot be used. e.g. `v-on:click="() => handler(listItem)"`. - `["method", "inline"]` ... Allow handlers by method binding. e.g. `v-on:click="handler"`. Allow inline handlers where method handlers cannot be used. e.g. `v-on:click="handler(listItem)"`. + - `["inline", "inline-function"]` ... Allow inline handlers. e.g. `v-on:click="handler()"`. Allow inline functions if they have at least 1 argument. e.g. `v-on:click="(arg1, arg2) => handler(arg1, arg2)"`. - `"inline-function"` ... Allow inline functions. e.g. `v-on:click="() => handler()"` - `"inline"` ... Allow inline handlers. e.g. `v-on:click="handler()"` - Second option - `ignoreIncludesComment` ... If `true`, do not report inline handlers or inline functions containing comments, even if the preferred style is `"method"`. Default is `false`. + - `allowInlineFuncSingleArg` ... Used in conjunction with `["method", "inline-function"]` or `["inline", "inline-function"]`. If `true`, allow inline functions with a single argument. Default is `false`. ### `["method", "inline-function"]` (Default) @@ -121,6 +123,68 @@ This rule aims to enforce a consistent style in `v-on` event handlers: +### `["inline", "inline-function"]` + + + +```vue + +``` + + + +### `["inline", "inline-function"]` with `allowInlineFuncSingleArg: true` + + + +```vue + +``` + + + ### `"inline-function"` diff --git a/lib/rules/v-on-handler-style.js b/lib/rules/v-on-handler-style.js index 10ff9b6b1..d5f98574a 100644 --- a/lib/rules/v-on-handler-style.js +++ b/lib/rules/v-on-handler-style.js @@ -11,6 +11,7 @@ const utils = require('../utils') * @typedef {'method' | 'inline' | 'inline-function'} HandlerKind * @typedef {object} ObjectOption * @property {boolean} [ignoreIncludesComment] + * @property {boolean} [allowInlineFuncSingleArg] */ /** @@ -33,8 +34,9 @@ function parseOptions(context) { const option = options[1] || {} const ignoreIncludesComment = !!option.ignoreIncludesComment + const allowInlineFuncSingleArg = option.allowInlineFuncSingleArg === true - return { allows, ignoreIncludesComment } + return { allows, ignoreIncludesComment, allowInlineFuncSingleArg } } /** @@ -112,33 +114,73 @@ module.exports = { url: 'https://eslint.vuejs.org/rules/v-on-handler-style.html' }, fixable: 'code', - schema: [ - { - oneOf: [ - { enum: ['inline', 'inline-function'] }, - { - type: 'array', - items: [ - { const: 'method' }, - { enum: ['inline', 'inline-function'] } - ], - uniqueItems: true, - additionalItems: false, - minItems: 2, - maxItems: 2 - } - ] - }, - { - type: 'object', - properties: { - ignoreIncludesComment: { - type: 'boolean' - } + schema: { + anyOf: [ + // `inline`, `inline-function` or `['method', 'inline']` + { + type: 'array', + items: [ + { + anyOf: [ + { enum: ['inline', 'inline-function'] }, + { + type: 'array', + items: [{ const: 'method' }, { const: 'inline' }], + uniqueItems: true, + additionalItems: false, + minItems: 2, + maxItems: 2 + } + ] + }, + { + type: 'object', + properties: { + ignoreIncludesComment: { + type: 'boolean' + } + }, + additionalProperties: false + } + ], + additionalItems: false, + minItems: 1, + maxItems: 2 }, - additionalProperties: false - } - ], + // `['method', 'inline-function']` or `['inline', 'inline-function']` + { + type: 'array', + items: [ + { + type: 'array', + items: [ + { enum: ['method', 'inline'] }, + { const: 'inline-function' } + ], + uniqueItems: true, + additionalItems: false, + minItems: 2, + maxItems: 2 + }, + { + type: 'object', + properties: { + ignoreIncludesComment: { + type: 'boolean' + }, + allowInlineFuncSingleArg: { + type: 'boolean' + } + }, + additionalProperties: false + } + ], + additionalItems: false, + minItems: 0, + maxItems: 2 + } + ] + }, messages: { preferMethodOverInline: 'Prefer method handler over inline handler in v-on.', @@ -162,7 +204,8 @@ module.exports = { }, /** @param {RuleContext} context */ create(context) { - const { allows, ignoreIncludesComment } = parseOptions(context) + const { allows, ignoreIncludesComment, allowInlineFuncSingleArg } = + parseOptions(context) /** @type {Set} */ const upperElements = new Set() @@ -530,6 +573,20 @@ module.exports = { if (allows[0] === 'inline-function') { return } + + if (allows[1] === 'inline-function') { + if (expression.params.length > 1) { + return + } + + if ( + expression.params.length === 1 && + allowInlineFuncSingleArg + ) { + return + } + } + for (const allow of allows) { if (verifyForInlineFunction(expression, allow)) { return diff --git a/tests/lib/rules/v-on-handler-style.js b/tests/lib/rules/v-on-handler-style.js index a169402f7..55d6423fb 100644 --- a/tests/lib/rules/v-on-handler-style.js +++ b/tests/lib/rules/v-on-handler-style.js @@ -71,6 +71,41 @@ tester.run('v-on-handler-style', rule, { { filename: 'test.vue', code: '' + }, + { + filename: 'test.vue', + code: ``, + options: [['inline', 'inline-function']] + }, + { + filename: 'test.vue', + code: ``, + options: [ + ['inline', 'inline-function'], + { allowInlineFuncSingleArg: true } + ] } ], invalid: [ @@ -191,6 +226,30 @@ tester.run('v-on-handler-style', rule, { } ] }, + { + filename: 'test.vue', + code: ``, + output: ``, + options: [['method', 'inline-function']], + errors: [ + { + message: 'Prefer method handler over inline function in v-on.', + line: 2, + column: 22 + }, + { + message: 'Prefer method handler over inline function in v-on.', + line: 3, + column: 22 + } + ] + }, { filename: 'test.vue', code: `