Skip to content

Commit 7609be6

Browse files
authored
New: Add vue/no-deprecated-data-object-declaration rule (#1083)
1 parent 7c24f5e commit 7609be6

6 files changed

+443
-0
lines changed

Diff for: docs/rules/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Enforce all the rules in this category, as well as all higher priority rules, wi
3939
| Rule ID | Description | |
4040
|:--------|:------------|:---|
4141
| [vue/no-async-in-computed-properties](./no-async-in-computed-properties.md) | disallow asynchronous actions in computed properties | |
42+
| [vue/no-deprecated-data-object-declaration](./no-deprecated-data-object-declaration.md) | disallow using deprecated object declaration on data | :wrench: |
4243
| [vue/no-deprecated-filter](./no-deprecated-filter.md) | disallow using deprecated filters syntax | |
4344
| [vue/no-deprecated-scope-attribute](./no-deprecated-scope-attribute.md) | disallow deprecated `scope` attribute (in Vue.js 2.5.0+) | :wrench: |
4445
| [vue/no-deprecated-slot-attribute](./no-deprecated-slot-attribute.md) | disallow deprecated `slot` attribute (in Vue.js 2.6.0+) | :wrench: |

Diff for: docs/rules/no-deprecated-data-object-declaration.md

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
---
2+
pageClass: rule-details
3+
sidebarDepth: 0
4+
title: vue/no-deprecated-data-object-declaration
5+
description: disallow using deprecated object declaration on data
6+
---
7+
# vue/no-deprecated-data-object-declaration
8+
> disallow using deprecated object declaration on data
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 object declaration on `data` property (in Vue.js 3.0.0+).
16+
The different from `vue/no-shared-component-data` is the root instance being also disallowed.
17+
18+
<eslint-code-block fix :rules="{'vue/no-deprecated-data-object-declaration': ['error']}">
19+
20+
```vue
21+
<script>
22+
/* ✗ BAD */
23+
createApp({
24+
data: {
25+
foo: null
26+
}
27+
}).mount('#app')
28+
export default {
29+
data: {
30+
foo: null
31+
}
32+
}
33+
34+
/* ✓ GOOD */
35+
export default {
36+
data () {
37+
return {
38+
foo: null
39+
}
40+
}
41+
}
42+
createApp({
43+
data () {
44+
return {
45+
foo: null
46+
}
47+
}
48+
}).mount('#app')
49+
</script>
50+
```
51+
52+
</eslint-code-block>
53+
54+
## :wrench: Options
55+
56+
Nothing.
57+
58+
## :books: Further reading
59+
60+
- [RFC: remove data object declaration](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0019-remove-data-object-declaration.md)
61+
62+
## :mag: Implementation
63+
64+
- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-deprecated-data-object-declaration.js)
65+
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-deprecated-data-object-declaration.js)

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

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ module.exports = {
77
extends: require.resolve('./base'),
88
rules: {
99
'vue/no-async-in-computed-properties': 'error',
10+
'vue/no-deprecated-data-object-declaration': 'error',
1011
'vue/no-deprecated-filter': 'error',
1112
'vue/no-deprecated-scope-attribute': 'error',
1213
'vue/no-deprecated-slot-attribute': 'error',

Diff for: lib/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ module.exports = {
4040
'no-boolean-default': require('./rules/no-boolean-default'),
4141
'no-confusing-v-for-v-if': require('./rules/no-confusing-v-for-v-if'),
4242
'no-custom-modifiers-on-v-model': require('./rules/no-custom-modifiers-on-v-model'),
43+
'no-deprecated-data-object-declaration': require('./rules/no-deprecated-data-object-declaration'),
4344
'no-deprecated-filter': require('./rules/no-deprecated-filter'),
4445
'no-deprecated-scope-attribute': require('./rules/no-deprecated-scope-attribute'),
4546
'no-deprecated-slot-attribute': require('./rules/no-deprecated-slot-attribute'),

Diff for: lib/rules/no-deprecated-data-object-declaration.js

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/**
2+
* @fileoverview disallow using deprecated object declaration on data
3+
* @author yoyo930021
4+
*/
5+
'use strict'
6+
7+
// ------------------------------------------------------------------------------
8+
// Requirements
9+
// ------------------------------------------------------------------------------
10+
11+
const utils = require('../utils')
12+
13+
function isOpenParen (token) {
14+
return token.type === 'Punctuator' && token.value === '('
15+
}
16+
17+
function isCloseParen (token) {
18+
return token.type === 'Punctuator' && token.value === ')'
19+
}
20+
21+
function getFirstAndLastTokens (node, sourceCode) {
22+
let first = sourceCode.getFirstToken(node)
23+
let last = sourceCode.getLastToken(node)
24+
25+
// If the value enclosed by parentheses, update the 'first' and 'last' by the parentheses.
26+
while (true) {
27+
const prev = sourceCode.getTokenBefore(first)
28+
const next = sourceCode.getTokenAfter(last)
29+
if (isOpenParen(prev) && isCloseParen(next)) {
30+
first = prev
31+
last = next
32+
} else {
33+
return { first, last }
34+
}
35+
}
36+
}
37+
38+
// ------------------------------------------------------------------------------
39+
// Rule Definition
40+
// ------------------------------------------------------------------------------
41+
42+
module.exports = {
43+
meta: {
44+
type: 'problem',
45+
docs: {
46+
description: 'disallow using deprecated object declaration on data',
47+
categories: ['vue3-essential'],
48+
url: 'https://eslint.vuejs.org/rules/no-deprecated-data-object-declaration.html'
49+
},
50+
fixable: 'code',
51+
schema: [],
52+
messages: {
53+
objectDeclarationIsDeprecated: "Object declaration on \'data\' property is deprecated. Using function declaration instead."
54+
}
55+
},
56+
57+
create (context) {
58+
const sourceCode = context.getSourceCode()
59+
60+
return utils.executeOnVue(context, (obj) => {
61+
obj.properties
62+
.filter(p =>
63+
p.type === 'Property' &&
64+
p.key.type === 'Identifier' &&
65+
p.key.name === 'data' &&
66+
p.value.type !== 'FunctionExpression' &&
67+
p.value.type !== 'ArrowFunctionExpression' &&
68+
p.value.type !== 'Identifier'
69+
)
70+
.forEach(p => {
71+
context.report({
72+
node: p,
73+
messageId: 'objectDeclarationIsDeprecated',
74+
fix (fixer) {
75+
const tokens = getFirstAndLastTokens(p.value, sourceCode)
76+
77+
return [
78+
fixer.insertTextBefore(tokens.first, 'function() {\nreturn '),
79+
fixer.insertTextAfter(tokens.last, ';\n}')
80+
]
81+
}
82+
})
83+
})
84+
})
85+
}
86+
}

0 commit comments

Comments
 (0)