Skip to content

Commit 335692e

Browse files
authored
New: Add vue/no-deprecated-v-on-number-modifiers rule (#1079)
1 parent 1ffcd01 commit 335692e

7 files changed

+387
-0
lines changed

Diff for: docs/rules/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ Enforce all the rules in this category, as well as all higher priority rules, wi
4444
| [vue/no-deprecated-slot-attribute](./no-deprecated-slot-attribute.md) | disallow deprecated `slot` attribute (in Vue.js 2.6.0+) | :wrench: |
4545
| [vue/no-deprecated-slot-scope-attribute](./no-deprecated-slot-scope-attribute.md) | disallow deprecated `slot-scope` attribute (in Vue.js 2.6.0+) | :wrench: |
4646
| [vue/no-deprecated-v-bind-sync](./no-deprecated-v-bind-sync.md) | disallow use of deprecated `.sync` modifier on `v-bind` directive (in Vue.js 3.0.0+) | :wrench: |
47+
| [vue/no-deprecated-v-on-number-modifiers](./no-deprecated-v-on-number-modifiers.md) | disallow using deprecated number (keycode) modifiers | :wrench: |
4748
| [vue/no-dupe-keys](./no-dupe-keys.md) | disallow duplication of field names | |
4849
| [vue/no-duplicate-attributes](./no-duplicate-attributes.md) | disallow duplication of attributes | |
4950
| [vue/no-lifecycle-after-await](./no-lifecycle-after-await.md) | disallow asynchronously registered lifecycle hooks | |

Diff for: docs/rules/no-deprecated-v-on-number-modifiers.md

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
---
2+
pageClass: rule-details
3+
sidebarDepth: 0
4+
title: vue/no-deprecated-v-on-number-modifiers
5+
description: disallow using deprecated number (keycode) modifiers (in Vue.js 3.0.0+)
6+
---
7+
# vue/no-deprecated-v-on-number-modifiers
8+
> disallow using deprecated number (keycode) modifiers (in Vue.js 3.0.0+)
9+
10+
- :gear: This rule is included in all of `"plugin:vue/vue3-essential"`, `"plugin:vue/vue3-strongly-recommended"` and `"plugin:vue/vue3-recommended"`.
11+
- :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
12+
13+
## :book: Rule Details
14+
15+
This rule reports use of deprecated `KeyboardEvent.keyCode` modifier on `v-on` directive (in Vue.js 3.0.0+)
16+
17+
<eslint-code-block fix :rules="{'vue/no-deprecated-v-on-number-modifiers': ['error']}">
18+
19+
```vue
20+
<template>
21+
<!-- ✓ GOOD -->
22+
<input v-on:keyup.page-down="onArrowUp">
23+
<input @keyup.page-down="onArrowUp">
24+
<input @keyup.9="onArrowUp"> <!-- 9 is KeyboardEvent.key -->
25+
26+
27+
<!-- ✗ BAD -->
28+
<input v-on:keyup.34="onArrowUp">
29+
<input @keyup.34="onArrowUp">
30+
</template>
31+
```
32+
33+
</eslint-code-block>
34+
35+
## :wrench: Options
36+
37+
Nothing.
38+
39+
## :couple: Related rules
40+
41+
- [valid-v-on]
42+
43+
[valid-v-on]: valid-v-on.md
44+
45+
## :books: Further reading
46+
47+
- [RFC: drop keycode support](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0014-drop-keycode-support.md)
48+
49+
## :mag: Implementation
50+
51+
- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-deprecated-v-on-number-modifiers.js)
52+
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-deprecated-v-on-number-modifiers.js)

Diff for: lib/configs/vue3-essential.js

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module.exports = {
1212
'vue/no-deprecated-slot-attribute': 'error',
1313
'vue/no-deprecated-slot-scope-attribute': 'error',
1414
'vue/no-deprecated-v-bind-sync': 'error',
15+
'vue/no-deprecated-v-on-number-modifiers': 'error',
1516
'vue/no-dupe-keys': 'error',
1617
'vue/no-duplicate-attributes': 'error',
1718
'vue/no-lifecycle-after-await': 'error',

Diff for: lib/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ module.exports = {
4545
'no-deprecated-slot-attribute': require('./rules/no-deprecated-slot-attribute'),
4646
'no-deprecated-slot-scope-attribute': require('./rules/no-deprecated-slot-scope-attribute'),
4747
'no-deprecated-v-bind-sync': require('./rules/no-deprecated-v-bind-sync'),
48+
'no-deprecated-v-on-number-modifiers': require('./rules/no-deprecated-v-on-number-modifiers'),
4849
'no-dupe-keys': require('./rules/no-dupe-keys'),
4950
'no-duplicate-attributes': require('./rules/no-duplicate-attributes'),
5051
'no-empty-pattern': require('./rules/no-empty-pattern'),

Diff for: lib/rules/no-deprecated-v-on-number-modifiers.js

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* @fileoverview disallow using deprecated number (keycode) modifiers
3+
* @author yoyo930021
4+
*/
5+
'use strict'
6+
7+
// ------------------------------------------------------------------------------
8+
// Requirements
9+
// ------------------------------------------------------------------------------
10+
11+
const utils = require('../utils')
12+
const keyCodeToKey = require('../utils/keycode-to-key.json')
13+
14+
// ------------------------------------------------------------------------------
15+
// Rule Definition
16+
// ------------------------------------------------------------------------------
17+
18+
module.exports = {
19+
meta: {
20+
type: 'problem',
21+
docs: {
22+
description: 'disallow using deprecated number (keycode) modifiers',
23+
categories: ['vue3-essential'],
24+
url: 'https://eslint.vuejs.org/rules/no-deprecated-v-on-number-modifiers.html'
25+
},
26+
fixable: 'code',
27+
schema: [],
28+
messages: {
29+
numberModifierIsDeprecated: "'KeyboardEvent.keyCode' modifier on 'v-on' directive is deprecated. Using 'KeyboardEvent.key' instead."
30+
}
31+
},
32+
33+
create (context) {
34+
return utils.defineTemplateBodyVisitor(context, {
35+
"VAttribute[directive=true][key.name.name='on']" (node) {
36+
const modifier = node.key.modifiers.find(mod => Number.isInteger(parseInt(mod.name, 10)))
37+
if (!modifier) return
38+
39+
const keyCodes = parseInt(modifier.name, 10)
40+
if (
41+
keyCodes > 9 || keyCodes < 0
42+
) {
43+
context.report({
44+
node,
45+
loc: node.loc,
46+
messageId: 'numberModifierIsDeprecated',
47+
fix: (fixer) => {
48+
const key = keyCodeToKey[keyCodes]
49+
if (!key) return
50+
51+
return fixer.replaceTextRange(modifier.range, `${key}`)
52+
}
53+
})
54+
}
55+
}
56+
})
57+
}
58+
}

Diff for: lib/utils/keycode-to-key.json

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
{
2+
"8": "backspace",
3+
"9": "tab",
4+
"13": "enter",
5+
"16": "shift",
6+
"17": "ctrl",
7+
"18": "alt",
8+
"19": "pause-break",
9+
"20": "caps-lock",
10+
"27": "escape",
11+
"33": "page-up",
12+
"34": "page-down",
13+
"35": "end",
14+
"36": "home",
15+
"37": "left-arrow",
16+
"38": "up-arrow",
17+
"39": "right-arrow",
18+
"40": "down-arrow",
19+
"45": "insert",
20+
"46": "delete",
21+
"48": "0",
22+
"49": "1",
23+
"50": "2",
24+
"51": "3",
25+
"52": "4",
26+
"53": "5",
27+
"54": "6",
28+
"55": "7",
29+
"56": "8",
30+
"57": "9",
31+
"65": "a",
32+
"66": "b",
33+
"67": "c",
34+
"68": "d",
35+
"69": "e",
36+
"70": "f",
37+
"71": "g",
38+
"72": "h",
39+
"73": "i",
40+
"74": "j",
41+
"75": "k",
42+
"76": "l",
43+
"77": "m",
44+
"78": "n",
45+
"79": "o",
46+
"80": "p",
47+
"81": "q",
48+
"82": "r",
49+
"83": "s",
50+
"84": "t",
51+
"85": "u",
52+
"86": "v",
53+
"87": "w",
54+
"88": "x",
55+
"89": "y",
56+
"90": "z",
57+
"91": "left-window-key",
58+
"92": "right-window-key",
59+
"93": "select-key",
60+
"96": "numpad-0",
61+
"97": "numpad-1",
62+
"98": "numpad-2",
63+
"99": "numpad-3",
64+
"100": "numpad-4",
65+
"101": "numpad-5",
66+
"102": "numpad-6",
67+
"103": "numpad-7",
68+
"104": "numpad-8",
69+
"105": "numpad-9",
70+
"106": "multiply",
71+
"107": "add",
72+
"109": "subtract",
73+
"110": "decimal-point",
74+
"111": "divide",
75+
"112": "f1",
76+
"113": "f2",
77+
"114": "f3",
78+
"115": "f4",
79+
"116": "f5",
80+
"117": "f6",
81+
"118": "f7",
82+
"119": "f8",
83+
"120": "f9",
84+
"121": "f10",
85+
"122": "f11",
86+
"123": "f12",
87+
"144": "num-lock",
88+
"145": "scroll-lock",
89+
"186": "semi-colon",
90+
"187": "equal-sign",
91+
"188": "comma",
92+
"189": "dash",
93+
"190": "period",
94+
"191": "forward-slash",
95+
"192": "grave-accent",
96+
"219": "open-bracket",
97+
"220": "back-slash",
98+
"221": "close-braket",
99+
"222": "single-quote"
100+
}

0 commit comments

Comments
 (0)