Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 6a49210

Browse files
Update vue/no-unsupported-features rule to support Vue 3.2 syntaxes. (#1599)
1 parent a1a5122 commit 6a49210

File tree

9 files changed

+226
-18
lines changed

9 files changed

+226
-18
lines changed

‎docs/rules/no-unsupported-features.md‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ This rule reports unsupported Vue.js syntax on the specified version.
2929
- `version` ... The `version` option accepts [the valid version range of `node-semver`](https://github.com/npm/node-semver#range-grammar). Set the version of Vue.js you are using. This option is required.
3030
- `ignores` ... You can use this `ignores` option to ignore the given features.
3131
The `"ignores"` option accepts an array of the following strings.
32+
- Vue.js 3.2.0+
33+
- `"v-memo"` ... [v-memo](https://v3.vuejs.org/api/directives.html#v-memo) directive.
34+
- `"v-bind-prop-modifier-shorthand"` ... `v-bind` with `.prop` modifier shorthand.
35+
- `"v-bind-attr-modifier"` ... `.attr` modifier on `v-bind` directive.
3236
- Vue.js 3.1.0+
3337
- `"is-attribute-with-vue-prefix"` ... [`is` attribute with `vue:` prefix](https://v3.vuejs.org/api/special-attributes.html#is)
3438
- Vue.js 3.0.0+
@@ -42,8 +46,6 @@ The `"ignores"` option accepts an array of the following strings.
4246
- `"v-slot"` ... [v-slot](https://v3.vuejs.org/api/directives.html#v-slot) directive.
4347
- Vue.js 2.5.0+
4448
- `"slot-scope-attribute"` ... [slot-scope](https://vuejs.org/v2/api/#slot-scope-deprecated) attributes.
45-
- Vue.js `">=2.6.0-beta.1 <=2.6.0-beta.3"` or 2.6 custom build
46-
- `"v-bind-prop-modifier-shorthand"` ... `v-bind` with `.prop` modifier shorthand.
4749

4850
### `{"version": "^2.6.0"}`
4951

@@ -97,6 +99,7 @@ The `"ignores"` option accepts an array of the following strings.
9799

98100
## :books: Further Reading
99101

102+
- [API - v-memo](https://v3.vuejs.org/api/directives.html#v-memo)
100103
- [API - v-is](https://v3.vuejs.org/api/directives.html#v-is)
101104
- [API - v-is (Old)](https://github.com/vuejs/docs-next/blob/008613756c3d781128d96b64a2d27f7598f8f548/src/api/directives.md#v-is)
102105
- [Guide - Dynamic Arguments](https://v3.vuejs.org/guide/template-syntax.html#dynamic-arguments)

‎lib/rules/no-unsupported-features.js‎

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,18 @@ const FEATURES = {
2020
// Vue.js 2.6.0+
2121
'dynamic-directive-arguments': require('./syntaxes/dynamic-directive-arguments'),
2222
'v-slot': require('./syntaxes/v-slot'),
23-
// >=2.6.0-beta.1 <=2.6.0-beta.3
24-
'v-bind-prop-modifier-shorthand': require('./syntaxes/v-bind-prop-modifier-shorthand'),
2523
// Vue.js 3.0.0+
2624
'v-model-argument': require('./syntaxes/v-model-argument'),
2725
'v-model-custom-modifiers': require('./syntaxes/v-model-custom-modifiers'),
2826
'v-is': require('./syntaxes/v-is'),
2927
'script-setup': require('./syntaxes/script-setup'),
3028
'style-css-vars-injection': require('./syntaxes/style-css-vars-injection'),
3129
// Vue.js 3.1.0+
32-
'is-attribute-with-vue-prefix': require('./syntaxes/is-attribute-with-vue-prefix')
30+
'is-attribute-with-vue-prefix': require('./syntaxes/is-attribute-with-vue-prefix'),
31+
// Vue.js 3.2.0+
32+
'v-memo': require('./syntaxes/v-memo'),
33+
'v-bind-prop-modifier-shorthand': require('./syntaxes/v-bind-prop-modifier-shorthand'),
34+
'v-bind-attr-modifier': require('./syntaxes/v-bind-attr-modifier')
3335
}
3436

3537
const SYNTAX_NAMES = /** @type {(keyof FEATURES)[]} */ (Object.keys(FEATURES))
@@ -93,9 +95,6 @@ module.exports = {
9395
forbiddenDynamicDirectiveArguments:
9496
'Dynamic arguments are not supported until Vue.js "2.6.0".',
9597
forbiddenVSlot: '`v-slot` are not supported until Vue.js "2.6.0".',
96-
// >=2.6.0-beta.1 <=2.6.0-beta.3
97-
forbiddenVBindPropModifierShorthand:
98-
'`.prop` shorthand are not supported except Vue.js ">=2.6.0-beta.1 <=2.6.0-beta.3".',
9998
// Vue.js 3.0.0+
10099
forbiddenVModelArgument:
101100
'Argument on `v-model` is not supported until Vue.js "3.0.0".',
@@ -108,7 +107,13 @@ module.exports = {
108107
'SFC CSS variable injection is not supported until Vue.js "3.0.3".',
109108
// Vue.js 3.1.0+
110109
forbiddenIsAttributeWithVuePrefix:
111-
'`is="vue:"` are not supported until Vue.js "3.1.0".'
110+
'`is="vue:"` are not supported until Vue.js "3.1.0".',
111+
// Vue.js 3.2.0+
112+
forbiddenVMemo: '`v-memo` are not supported until Vue.js "3.2.0".',
113+
forbiddenVBindPropModifierShorthand:
114+
'`.prop` shorthand are not supported until Vue.js "3.2.0".',
115+
forbiddenVBindAttrModifier:
116+
'`.attr` modifiers on `v-bind` are not supported until Vue.js "3.2.0".'
112117
}
113118
},
114119
/** @param {RuleContext} context */
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* @author Yosuke Ota
3+
* See LICENSE file in root directory for full license.
4+
*/
5+
'use strict'
6+
7+
module.exports = {
8+
supported: '>=3.2.0',
9+
/** @param {RuleContext} context @returns {TemplateListener} */
10+
createTemplateBodyVisitor(context) {
11+
/**
12+
* Reports `v-bind.attr` node
13+
* @param { VIdentifier } mod node of `v-bind.attr`
14+
* @returns {void}
15+
*/
16+
function report(mod) {
17+
context.report({
18+
node: mod,
19+
messageId: 'forbiddenVBindAttrModifier'
20+
})
21+
}
22+
23+
return {
24+
"VAttribute[directive=true][key.name.name='bind']"(node) {
25+
const attrMod = node.key.modifiers.find((m) => m.name === 'attr')
26+
if (attrMod) {
27+
report(attrMod)
28+
}
29+
}
30+
}
31+
}
32+
}

‎lib/rules/syntaxes/v-bind-prop-modifier-shorthand.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
'use strict'
66

77
module.exports = {
8-
supported: '>=2.6.0-beta.1 <=2.6.0-beta.3',
8+
supported: '>=3.2.0 || >=2.6.0-beta.1 <=2.6.0-beta.3',
99
/** @param {RuleContext} context @returns {TemplateListener} */
1010
createTemplateBodyVisitor(context) {
1111
/**

‎lib/rules/syntaxes/v-is.js‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,18 @@ module.exports = {
1010
createTemplateBodyVisitor(context) {
1111
/**
1212
* Reports `v-is` node
13-
* @param {VDirective} vSlotAttr node of `v-is`
13+
* @param {VDirective} vIsAttr node of `v-is`
1414
* @returns {void}
1515
*/
16-
function reportVSlot(vSlotAttr) {
16+
function reportVIs(vIsAttr) {
1717
context.report({
18-
node: vSlotAttr.key,
18+
node: vIsAttr.key,
1919
messageId: 'forbiddenVIs'
2020
})
2121
}
2222

2323
return {
24-
"VAttribute[directive=true][key.name.name='is']": reportVSlot
24+
"VAttribute[directive=true][key.name.name='is']": reportVIs
2525
}
2626
}
2727
}

‎lib/rules/syntaxes/v-memo.js‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* @author Yosuke Ota
3+
* See LICENSE file in root directory for full license.
4+
*/
5+
'use strict'
6+
module.exports = {
7+
supported: '>=3.2.0',
8+
/** @param {RuleContext} context @returns {TemplateListener} */
9+
createTemplateBodyVisitor(context) {
10+
/**
11+
* Reports `v-is` node
12+
* @param {VDirective} vMemoAttr node of `v-is`
13+
* @returns {void}
14+
*/
15+
function reportVMemo(vMemoAttr) {
16+
context.report({
17+
node: vMemoAttr.key,
18+
messageId: 'forbiddenVMemo'
19+
})
20+
}
21+
22+
return {
23+
"VAttribute[directive=true][key.name.name='memo']": reportVMemo
24+
}
25+
}
26+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/**
2+
* @author Yosuke Ota
3+
* See LICENSE file in root directory for full license.
4+
*/
5+
'use strict'
6+
7+
const RuleTester = require('eslint').RuleTester
8+
const rule = require('../../../../lib/rules/no-unsupported-features')
9+
const utils = require('./utils')
10+
11+
const buildOptions = utils.optionsBuilder('v-bind-attr-modifier', '^3.1.0')
12+
const tester = new RuleTester({
13+
parser: require.resolve('vue-eslint-parser'),
14+
parserOptions: {
15+
ecmaVersion: 2019
16+
}
17+
})
18+
19+
tester.run('no-unsupported-features/v-bind-attr-modifier', rule, {
20+
valid: [
21+
{
22+
code: `
23+
<template>
24+
<div :foo.attr="foo" />
25+
</template>`,
26+
options: buildOptions({ version: '^3.2.0' })
27+
},
28+
{
29+
code: `
30+
<template>
31+
<div v-bind:attr="foo" />
32+
</template>`,
33+
options: buildOptions()
34+
},
35+
{
36+
code: `
37+
<template>
38+
<div :foo.attr="foo" />
39+
</template>`,
40+
options: buildOptions({
41+
version: '^2.5.0',
42+
ignores: ['v-bind-attr-modifier']
43+
})
44+
}
45+
],
46+
invalid: [
47+
{
48+
code: `
49+
<template>
50+
<div :foo.attr="foo" />
51+
</template>`,
52+
options: buildOptions(),
53+
errors: [
54+
{
55+
message:
56+
'`.attr` modifiers on `v-bind` are not supported until Vue.js "3.2.0".',
57+
line: 3
58+
}
59+
]
60+
}
61+
]
62+
})

‎tests/lib/rules/no-unsupported-features/v-bind-prop-modifier-shorthand.js‎

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ tester.run('no-unsupported-features/v-bind-prop-modifier-shorthand', rule, {
2828
</template>`,
2929
options: buildOptions({ version: '2.6.0-beta.1' })
3030
},
31+
{
32+
code: `
33+
<template>
34+
<a .href="'/xxx'" />
35+
</template>`,
36+
options: buildOptions({ version: '3.2.0' })
37+
},
3138
{
3239
code: `
3340
<template>
@@ -63,8 +70,7 @@ tester.run('no-unsupported-features/v-bind-prop-modifier-shorthand', rule, {
6370
</template>`,
6471
errors: [
6572
{
66-
message:
67-
'`.prop` shorthand are not supported except Vue.js ">=2.6.0-beta.1 <=2.6.0-beta.3".',
73+
message: '`.prop` shorthand are not supported until Vue.js "3.2.0".',
6874
line: 3
6975
}
7076
]
@@ -81,8 +87,24 @@ tester.run('no-unsupported-features/v-bind-prop-modifier-shorthand', rule, {
8187
</template>`,
8288
errors: [
8389
{
84-
message:
85-
'`.prop` shorthand are not supported except Vue.js ">=2.6.0-beta.1 <=2.6.0-beta.3".',
90+
message: '`.prop` shorthand are not supported until Vue.js "3.2.0".',
91+
line: 3
92+
}
93+
]
94+
},
95+
{
96+
code: `
97+
<template>
98+
<a .href="'/xxx'" />
99+
</template>`,
100+
options: buildOptions({ version: '3.1.0' }),
101+
output: `
102+
<template>
103+
<a :href.prop="'/xxx'" />
104+
</template>`,
105+
errors: [
106+
{
107+
message: '`.prop` shorthand are not supported until Vue.js "3.2.0".',
86108
line: 3
87109
}
88110
]
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* @author Yosuke Ota
3+
* See LICENSE file in root directory for full license.
4+
*/
5+
'use strict'
6+
7+
const RuleTester = require('eslint').RuleTester
8+
const rule = require('../../../../lib/rules/no-unsupported-features')
9+
const utils = require('./utils')
10+
11+
const buildOptions = utils.optionsBuilder('v-memo', '^3.1.0')
12+
const tester = new RuleTester({
13+
parser: require.resolve('vue-eslint-parser'),
14+
parserOptions: {
15+
ecmaVersion: 2019
16+
}
17+
})
18+
19+
tester.run('no-unsupported-features/v-memo', rule, {
20+
valid: [
21+
{
22+
code: `
23+
<template>
24+
<div v-memo="foo" />
25+
</template>`,
26+
options: buildOptions({ version: '^3.2.0' })
27+
},
28+
{
29+
code: `
30+
<template>
31+
<div :memo="foo" />
32+
</template>`,
33+
options: buildOptions()
34+
},
35+
{
36+
code: `
37+
<template>
38+
<div v-memo="foo" />
39+
</template>`,
40+
options: buildOptions({ version: '^2.5.0', ignores: ['v-memo'] })
41+
}
42+
],
43+
invalid: [
44+
{
45+
code: `
46+
<template>
47+
<div v-memo="foo" />
48+
</template>`,
49+
options: buildOptions(),
50+
errors: [
51+
{
52+
message: '`v-memo` are not supported until Vue.js "3.2.0".',
53+
line: 3
54+
}
55+
]
56+
}
57+
]
58+
})

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /