Skip to content

Commit 9f2cec1

Browse files
ota-meshimysticatea
authored andcommitted
New: add vue/no-deprecated-scope-attribute rule (#838)
1 parent ff6b275 commit 9f2cec1

File tree

6 files changed

+205
-0
lines changed

6 files changed

+205
-0
lines changed

Diff for: docs/rules/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ For example:
152152
| [vue/keyword-spacing](./keyword-spacing.md) | enforce consistent spacing before and after keywords | :wrench: |
153153
| [vue/match-component-file-name](./match-component-file-name.md) | require component name property to match its file name | |
154154
| [vue/no-boolean-default](./no-boolean-default.md) | disallow boolean defaults | :wrench: |
155+
| [vue/no-deprecated-scope-attribute](./no-deprecated-scope-attribute.md) | disallow deprecated `scope` attribute (in Vue.js 2.5.0+) | :wrench: |
155156
| [vue/no-empty-pattern](./no-empty-pattern.md) | disallow empty destructuring patterns | |
156157
| [vue/no-restricted-syntax](./no-restricted-syntax.md) | disallow specified syntax | |
157158
| [vue/object-curly-spacing](./object-curly-spacing.md) | enforce consistent spacing inside braces | :wrench: |

Diff for: docs/rules/no-deprecated-scope-attribute.md

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
---
2+
pageClass: rule-details
3+
sidebarDepth: 0
4+
title: vue/no-deprecated-scope-attribute
5+
description: disallow deprecated `scope` attribute (in Vue.js 2.5.0+)
6+
---
7+
# vue/no-deprecated-scope-attribute
8+
> disallow deprecated `scope` attribute (in Vue.js 2.5.0+)
9+
10+
- :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.
11+
12+
## :book: Rule Details
13+
14+
This rule reports deprecated `scope` attribute in Vue.js v2.5.0+.
15+
16+
<eslint-code-block fix :rules="{'vue/no-deprecated-scope-attribute': ['error']}">
17+
18+
```vue
19+
<template>
20+
<ListComponent>
21+
<!-- ✓ GOOD -->
22+
<template v-slot:name="props">
23+
{{ props.title }}
24+
</template>
25+
<template slot="name" slot-scope="props">
26+
{{ props.title }}
27+
</template>
28+
</ListComponent>
29+
<ListComponent>
30+
<!-- ✗ BAD -->
31+
<template slot="name" scope="props">
32+
{{ props.title }}
33+
</template>
34+
</ListComponent>
35+
</template>
36+
```
37+
38+
</eslint-code-block>
39+
40+
## :books: Further reading
41+
42+
- [API - scope](https://vuejs.org/v2/api/#scope-removed)
43+
44+
## :mag: Implementation
45+
46+
- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-deprecated-scope-attribute.js)
47+
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-deprecated-scope-attribute.js)

Diff for: lib/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ module.exports = {
3636
'no-async-in-computed-properties': require('./rules/no-async-in-computed-properties'),
3737
'no-boolean-default': require('./rules/no-boolean-default'),
3838
'no-confusing-v-for-v-if': require('./rules/no-confusing-v-for-v-if'),
39+
'no-deprecated-scope-attribute': require('./rules/no-deprecated-scope-attribute'),
3940
'no-dupe-keys': require('./rules/no-dupe-keys'),
4041
'no-duplicate-attributes': require('./rules/no-duplicate-attributes'),
4142
'no-empty-pattern': require('./rules/no-empty-pattern'),

Diff for: lib/rules/no-deprecated-scope-attribute.js

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* @author Yosuke Ota
3+
* See LICENSE file in root directory for full license.
4+
*/
5+
'use strict'
6+
7+
const utils = require('../utils')
8+
const scopeAttribute = require('./syntaxes/scope-attribute')
9+
10+
module.exports = {
11+
meta: {
12+
type: 'suggestion',
13+
docs: {
14+
description: 'disallow deprecated `scope` attribute (in Vue.js 2.5.0+)',
15+
category: undefined,
16+
url: 'https://eslint.vuejs.org/rules/no-deprecated-scope-attribute.html'
17+
},
18+
fixable: 'code',
19+
schema: [],
20+
messages: {
21+
forbiddenScopeAttribute: '`scope` attributes are deprecated.'
22+
}
23+
},
24+
create (context) {
25+
const templateBodyVisitor = scopeAttribute.createTemplateBodyVisitor(context)
26+
return utils.defineTemplateBodyVisitor(context, templateBodyVisitor)
27+
}
28+
}

Diff for: lib/rules/syntaxes/scope-attribute.js

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
* @author Yosuke Ota
3+
* See LICENSE file in root directory for full license.
4+
*/
5+
'use strict'
6+
module.exports = {
7+
deprecated: '2.5.0',
8+
createTemplateBodyVisitor (context) {
9+
/**
10+
* Reports `scope` node
11+
* @param {VDirectiveKey} scopeKey node of `scope`
12+
* @returns {void}
13+
*/
14+
function reportScope (scopeKey) {
15+
context.report({
16+
node: scopeKey,
17+
messageId: 'forbiddenScopeAttribute',
18+
// fix to use `slot-scope`
19+
fix: fixer => fixer.replaceText(scopeKey, 'slot-scope')
20+
})
21+
}
22+
23+
return {
24+
"VAttribute[directive=true] > VDirectiveKey[name.name='scope']": reportScope
25+
}
26+
}
27+
}

Diff for: tests/lib/rules/no-deprecated-scope-attribute.js

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
'use strict'
2+
3+
const RuleTester = require('eslint').RuleTester
4+
const rule = require('../../../lib/rules/no-deprecated-scope-attribute')
5+
6+
const tester = new RuleTester({
7+
parser: 'vue-eslint-parser',
8+
parserOptions: {
9+
ecmaVersion: 2015
10+
}
11+
})
12+
13+
tester.run('no-deprecated-scope-attribute', rule, {
14+
valid: [
15+
`<template>
16+
<LinkList>
17+
<a v-slot:name />
18+
</LinkList>
19+
</template>`,
20+
`<template>
21+
<LinkList>
22+
<a #name />
23+
</LinkList>
24+
</template>`,
25+
`<template>
26+
<LinkList>
27+
<a v-slot="{a}" />
28+
</LinkList>
29+
</template>`,
30+
`<template>
31+
<LinkList>
32+
<a #default="{a}" />
33+
</LinkList>
34+
</template>`,
35+
`<template>
36+
<LinkList>
37+
<a slot="name" />
38+
</LinkList>
39+
</template>`,
40+
`<template>
41+
<LinkList>
42+
<a slot-scope="{a}" />
43+
</LinkList>
44+
</template>`,
45+
`<template>
46+
<LinkList>
47+
<a />
48+
</LinkList>
49+
</template>`
50+
],
51+
invalid: [
52+
{
53+
code: `
54+
<template>
55+
<LinkList>
56+
<template scope="{a}">
57+
<a />
58+
</template>
59+
</LinkList>
60+
</template>`,
61+
output: `
62+
<template>
63+
<LinkList>
64+
<template slot-scope="{a}">
65+
<a />
66+
</template>
67+
</LinkList>
68+
</template>`,
69+
errors: [
70+
{
71+
message: '`scope` attributes are deprecated.',
72+
line: 4
73+
}
74+
]
75+
},
76+
{
77+
code: `
78+
<template>
79+
<LinkList>
80+
<template slot="name" scope="{a}">
81+
<a />
82+
</template>
83+
</LinkList>
84+
</template>`,
85+
output: `
86+
<template>
87+
<LinkList>
88+
<template slot="name" slot-scope="{a}">
89+
<a />
90+
</template>
91+
</LinkList>
92+
</template>`,
93+
errors: [
94+
{
95+
message: '`scope` attributes are deprecated.',
96+
line: 4
97+
}
98+
]
99+
}
100+
]
101+
})

0 commit comments

Comments
 (0)