Skip to content

Commit 0437972

Browse files
authored
Support Nuxt.js's asyncData in various rules (#1679)
* Support `asyncData` in `vue/no-undef-properties` * Support `asyncData` in `vue/no-dupe-keys` * Support `asyncData` in `vue/no-reserved-keys` * Support `asyncData` in `vue/no-template-shadow` * Support `asyncData` in `vue/no-unused-properties` * Lint
1 parent 44ff0e0 commit 0437972

11 files changed

+183
-8
lines changed

lib/rules/no-dupe-keys.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,14 @@ const utils = require('../utils')
1414
// Rule Definition
1515
// ------------------------------------------------------------------------------
1616
/** @type {GroupName[]} */
17-
const GROUP_NAMES = ['props', 'computed', 'data', 'methods', 'setup']
17+
const GROUP_NAMES = [
18+
'props',
19+
'computed',
20+
'data',
21+
'asyncData',
22+
'methods',
23+
'setup'
24+
]
1825

1926
module.exports = {
2027
meta: {

lib/rules/no-reserved-keys.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,14 @@ const utils = require('../utils')
1616

1717
const RESERVED_KEYS = require('../utils/vue-reserved.json')
1818
/** @type {GroupName[]} */
19-
const GROUP_NAMES = ['props', 'computed', 'data', 'methods', 'setup']
19+
const GROUP_NAMES = [
20+
'props',
21+
'computed',
22+
'data',
23+
'asyncData',
24+
'methods',
25+
'setup'
26+
]
2027

2128
module.exports = {
2229
meta: {
@@ -76,7 +83,10 @@ module.exports = {
7683
utils.executeOnVue(context, (obj) => {
7784
const properties = utils.iterateProperties(obj, groups)
7885
for (const o of properties) {
79-
if (o.groupName === 'data' && o.name[0] === '_') {
86+
if (
87+
(o.groupName === 'data' || o.groupName === 'asyncData') &&
88+
o.name[0] === '_'
89+
) {
8090
context.report({
8191
node: o.node,
8292
messageId: 'startsWithUnderscore',

lib/rules/no-template-shadow.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,14 @@ const utils = require('../utils')
1919
// ------------------------------------------------------------------------------
2020

2121
/** @type {GroupName[]} */
22-
const GROUP_NAMES = ['props', 'computed', 'data', 'methods', 'setup']
22+
const GROUP_NAMES = [
23+
'props',
24+
'computed',
25+
'data',
26+
'asyncData',
27+
'methods',
28+
'setup'
29+
]
2330

2431
module.exports = {
2532
meta: {

lib/rules/no-undef-properties.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ const {
3232
// ------------------------------------------------------------------------------
3333

3434
const GROUP_PROPERTY = 'props'
35+
const GROUP_ASYNC_DATA = 'asyncData' // Nuxt.js
3536
const GROUP_DATA = 'data'
3637
const GROUP_COMPUTED_PROPERTY = 'computed'
3738
const GROUP_METHODS = 'methods'
@@ -334,6 +335,7 @@ module.exports = {
334335
node,
335336
new Set([
336337
GROUP_PROPERTY,
338+
GROUP_ASYNC_DATA,
337339
GROUP_DATA,
338340
GROUP_COMPUTED_PROPERTY,
339341
GROUP_SETUP,
@@ -342,7 +344,8 @@ module.exports = {
342344
])
343345
)) {
344346
const propertyMap =
345-
prop.groupName === GROUP_DATA &&
347+
(prop.groupName === GROUP_DATA ||
348+
prop.groupName === GROUP_ASYNC_DATA) &&
346349
prop.type === 'object' &&
347350
prop.property.value.type === 'ObjectExpression'
348351
? getObjectPropertyMap(prop.property.value)

lib/rules/no-unused-properties.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ const {
5555

5656
const GROUP_PROPERTY = 'props'
5757
const GROUP_DATA = 'data'
58+
const GROUP_ASYNC_DATA = 'asyncData'
5859
const GROUP_COMPUTED_PROPERTY = 'computed'
5960
const GROUP_METHODS = 'methods'
6061
const GROUP_SETUP = 'setup'
@@ -64,6 +65,7 @@ const GROUP_EXPOSE = 'expose'
6465
const PROPERTY_LABEL = {
6566
props: 'property',
6667
data: 'data',
68+
asyncData: 'async data',
6769
computed: 'computed property',
6870
methods: 'method',
6971
setup: 'property returned from `setup()`',
@@ -213,6 +215,7 @@ module.exports = {
213215
enum: [
214216
GROUP_PROPERTY,
215217
GROUP_DATA,
218+
GROUP_ASYNC_DATA,
216219
GROUP_COMPUTED_PROPERTY,
217220
GROUP_METHODS,
218221
GROUP_SETUP
@@ -350,7 +353,8 @@ module.exports = {
350353
// used
351354
if (
352355
deepData &&
353-
property.groupName === 'data' &&
356+
(property.groupName === 'data' ||
357+
property.groupName === 'asyncData') &&
354358
property.type === 'object'
355359
) {
356360
// Check the deep properties of the data option.

lib/utils/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
* @typedef { {key: string | null, value: BlockStatement | null} } ComponentComputedProperty
2424
*/
2525
/**
26-
* @typedef { 'props' | 'data' | 'computed' | 'setup' | 'watch' | 'methods' | 'provide' | 'inject' | 'expose' } GroupName
26+
* @typedef { 'props' | 'asyncData' | 'data' | 'computed' | 'setup' | 'watch' | 'methods' | 'provide' | 'inject' | 'expose' } GroupName
2727
* @typedef { { type: 'array', name: string, groupName: GroupName, node: Literal | TemplateLiteral } } ComponentArrayPropertyData
2828
* @typedef { { type: 'object', name: string, groupName: GroupName, node: Identifier | Literal | TemplateLiteral, property: Property } } ComponentObjectPropertyData
2929
* @typedef { ComponentArrayPropertyData | ComponentObjectPropertyData } ComponentPropertyData

tests/lib/rules/no-dupe-keys.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,29 @@ ruleTester.run('no-dupe-keys', rule, {
709709
}
710710
]
711711
},
712+
{
713+
filename: 'test.vue',
714+
code: `
715+
export default {
716+
asyncData() {
717+
return {
718+
foo: 1
719+
}
720+
},
721+
data() {
722+
return {
723+
foo: 2
724+
}
725+
},
726+
}
727+
`,
728+
errors: [
729+
{
730+
message: "Duplicated key 'foo'.",
731+
line: 10
732+
}
733+
]
734+
},
712735
{
713736
filename: 'test.js',
714737
code: `

tests/lib/rules/no-reserved-keys.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,25 @@ ruleTester.run('no-reserved-keys', rule, {
156156
}
157157
]
158158
},
159+
{
160+
filename: 'test.js',
161+
code: `
162+
new Vue({
163+
asyncData () {
164+
return {
165+
$el: ''
166+
}
167+
}
168+
})
169+
`,
170+
parserOptions: { ecmaVersion: 6 },
171+
errors: [
172+
{
173+
message: "Key '$el' is reserved.",
174+
line: 5
175+
}
176+
]
177+
},
159178
{
160179
filename: 'test.js',
161180
code: `
@@ -209,6 +228,23 @@ ruleTester.run('no-reserved-keys', rule, {
209228
}
210229
]
211230
},
231+
{
232+
filename: 'test.js',
233+
code: `
234+
new Vue({
235+
asyncData: () => ({
236+
_foo: String
237+
})
238+
})
239+
`,
240+
parserOptions: { ecmaVersion: 6 },
241+
errors: [
242+
{
243+
message: "Keys starting with '_' are reserved in '_foo' group.",
244+
line: 4
245+
}
246+
]
247+
},
212248
{
213249
filename: 'test.js',
214250
code: `

tests/lib/rules/no-template-shadow.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,28 @@ ruleTester.run('no-template-shadow', rule, {
250250
}
251251
]
252252
},
253+
{
254+
filename: 'test.vue',
255+
code: `<template>
256+
<div v-for="i in 5"></div>
257+
</template>
258+
<script>
259+
export default {
260+
asyncData() {
261+
return {
262+
i: 27,
263+
}
264+
}
265+
}
266+
</script>`,
267+
errors: [
268+
{
269+
message: "Variable 'i' is already declared in the upper scope.",
270+
type: 'Identifier',
271+
line: 2
272+
}
273+
]
274+
},
253275
{
254276
filename: 'test.vue',
255277
code: `<template>

tests/lib/rules/no-undef-properties.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,23 @@ tester.run('no-undef-properties', rule, {
6767
</script>
6868
`
6969
},
70+
{
71+
filename: 'test.vue',
72+
code: `
73+
<template>
74+
<div> {{ foo }} </div>
75+
</template>
76+
<script>
77+
export default {
78+
asyncData() {
79+
return {
80+
foo: 42
81+
}
82+
},
83+
};
84+
</script>
85+
`
86+
},
7087
//default ignores
7188
{
7289
filename: 'test.vue',

tests/lib/rules/no-unused-properties.js

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const tester = new RuleTester({
1616
})
1717

1818
const allOptions = [
19-
{ groups: ['props', 'computed', 'data', 'methods', 'setup'] }
19+
{ groups: ['props', 'computed', 'data', 'asyncData', 'methods', 'setup'] }
2020
]
2121
const deepDataOptions = [{ groups: ['data'], deepData: true }]
2222

@@ -647,6 +647,26 @@ tester.run('no-unused-properties', rule, {
647647
options: allOptions
648648
},
649649

650+
// async data passed in a component
651+
{
652+
filename: 'test.vue',
653+
code: `
654+
<template>
655+
<counter :count="foo" />
656+
</template>
657+
<script>
658+
export default {
659+
asyncData() {
660+
return {
661+
foo: 2
662+
}
663+
}
664+
}
665+
</script>
666+
`,
667+
options: allOptions
668+
},
669+
650670
// ignores unused data when marked with eslint-disable
651671
{
652672
filename: 'test.vue',
@@ -1709,6 +1729,32 @@ tester.run('no-unused-properties', rule, {
17091729
]
17101730
},
17111731

1732+
// unused async data
1733+
{
1734+
filename: 'test.vue',
1735+
code: `
1736+
<template>
1737+
<div>{{ cont }}</div>
1738+
</template>
1739+
<script>
1740+
export default {
1741+
asyncData () {
1742+
return {
1743+
count: 2
1744+
};
1745+
}
1746+
};
1747+
</script>
1748+
`,
1749+
options: [{ groups: ['props', 'computed', 'data', 'asyncData'] }],
1750+
errors: [
1751+
{
1752+
message: "'count' of async data found, but never used.",
1753+
line: 9
1754+
}
1755+
]
1756+
},
1757+
17121758
// unused computed property
17131759
{
17141760
filename: 'test.vue',

0 commit comments

Comments
 (0)