Skip to content

Commit

Permalink
New: Add vue/no-deprecated-data-object-declaration rule (#1083)
Browse files Browse the repository at this point in the history
  • Loading branch information
yoyo930021 authored Apr 21, 2020
1 parent 7c24f5e commit 7609be6
Show file tree
Hide file tree
Showing 6 changed files with 443 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/rules/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Enforce all the rules in this category, as well as all higher priority rules, wi
| Rule ID | Description | |
|:--------|:------------|:---|
| [vue/no-async-in-computed-properties](./no-async-in-computed-properties.md) | disallow asynchronous actions in computed properties | |
| [vue/no-deprecated-data-object-declaration](./no-deprecated-data-object-declaration.md) | disallow using deprecated object declaration on data | :wrench: |
| [vue/no-deprecated-filter](./no-deprecated-filter.md) | disallow using deprecated filters syntax | |
| [vue/no-deprecated-scope-attribute](./no-deprecated-scope-attribute.md) | disallow deprecated `scope` attribute (in Vue.js 2.5.0+) | :wrench: |
| [vue/no-deprecated-slot-attribute](./no-deprecated-slot-attribute.md) | disallow deprecated `slot` attribute (in Vue.js 2.6.0+) | :wrench: |
Expand Down
65 changes: 65 additions & 0 deletions docs/rules/no-deprecated-data-object-declaration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
pageClass: rule-details
sidebarDepth: 0
title: vue/no-deprecated-data-object-declaration
description: disallow using deprecated object declaration on data
---
# vue/no-deprecated-data-object-declaration
> disallow using deprecated object declaration on data
- :gear: This rule is included in all of `"plugin:vue/vue3-essential"`, `"plugin:vue/vue3-strongly-recommended"` and `"plugin:vue/vue3-recommended"`.
- :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.

## :book: Rule Details

This rule reports use of deprecated object declaration on `data` property (in Vue.js 3.0.0+).
The different from `vue/no-shared-component-data` is the root instance being also disallowed.

<eslint-code-block fix :rules="{'vue/no-deprecated-data-object-declaration': ['error']}">

```vue
<script>
/* ✗ BAD */
createApp({
data: {
foo: null
}
}).mount('#app')
export default {
data: {
foo: null
}
}
/* ✓ GOOD */
export default {
data () {
return {
foo: null
}
}
}
createApp({
data () {
return {
foo: null
}
}
}).mount('#app')
</script>
```

</eslint-code-block>

## :wrench: Options

Nothing.

## :books: Further reading

- [RFC: remove data object declaration](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0019-remove-data-object-declaration.md)

## :mag: Implementation

- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-deprecated-data-object-declaration.js)
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-deprecated-data-object-declaration.js)
1 change: 1 addition & 0 deletions lib/configs/vue3-essential.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module.exports = {
extends: require.resolve('./base'),
rules: {
'vue/no-async-in-computed-properties': 'error',
'vue/no-deprecated-data-object-declaration': 'error',
'vue/no-deprecated-filter': 'error',
'vue/no-deprecated-scope-attribute': 'error',
'vue/no-deprecated-slot-attribute': 'error',
Expand Down
1 change: 1 addition & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ module.exports = {
'no-boolean-default': require('./rules/no-boolean-default'),
'no-confusing-v-for-v-if': require('./rules/no-confusing-v-for-v-if'),
'no-custom-modifiers-on-v-model': require('./rules/no-custom-modifiers-on-v-model'),
'no-deprecated-data-object-declaration': require('./rules/no-deprecated-data-object-declaration'),
'no-deprecated-filter': require('./rules/no-deprecated-filter'),
'no-deprecated-scope-attribute': require('./rules/no-deprecated-scope-attribute'),
'no-deprecated-slot-attribute': require('./rules/no-deprecated-slot-attribute'),
Expand Down
86 changes: 86 additions & 0 deletions lib/rules/no-deprecated-data-object-declaration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/**
* @fileoverview disallow using deprecated object declaration on data
* @author yoyo930021
*/
'use strict'

// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------

const utils = require('../utils')

function isOpenParen (token) {
return token.type === 'Punctuator' && token.value === '('
}

function isCloseParen (token) {
return token.type === 'Punctuator' && token.value === ')'
}

function getFirstAndLastTokens (node, sourceCode) {
let first = sourceCode.getFirstToken(node)
let last = sourceCode.getLastToken(node)

// If the value enclosed by parentheses, update the 'first' and 'last' by the parentheses.
while (true) {
const prev = sourceCode.getTokenBefore(first)
const next = sourceCode.getTokenAfter(last)
if (isOpenParen(prev) && isCloseParen(next)) {
first = prev
last = next
} else {
return { first, last }
}
}
}

// ------------------------------------------------------------------------------
// Rule Definition
// ------------------------------------------------------------------------------

module.exports = {
meta: {
type: 'problem',
docs: {
description: 'disallow using deprecated object declaration on data',
categories: ['vue3-essential'],
url: 'https://eslint.vuejs.org/rules/no-deprecated-data-object-declaration.html'
},
fixable: 'code',
schema: [],
messages: {
objectDeclarationIsDeprecated: "Object declaration on \'data\' property is deprecated. Using function declaration instead."
}
},

create (context) {
const sourceCode = context.getSourceCode()

return utils.executeOnVue(context, (obj) => {
obj.properties
.filter(p =>
p.type === 'Property' &&
p.key.type === 'Identifier' &&
p.key.name === 'data' &&
p.value.type !== 'FunctionExpression' &&
p.value.type !== 'ArrowFunctionExpression' &&
p.value.type !== 'Identifier'
)
.forEach(p => {
context.report({
node: p,
messageId: 'objectDeclarationIsDeprecated',
fix (fixer) {
const tokens = getFirstAndLastTokens(p.value, sourceCode)

return [
fixer.insertTextBefore(tokens.first, 'function() {\nreturn '),
fixer.insertTextAfter(tokens.last, ';\n}')
]
}
})
})
})
}
}
Loading

0 comments on commit 7609be6

Please sign in to comment.