-
-
Notifications
You must be signed in to change notification settings - Fork 675
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
vue/no-computed-properties-in-data
rule (#1653)
- Loading branch information
Showing
6 changed files
with
286 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
--- | ||
pageClass: rule-details | ||
sidebarDepth: 0 | ||
title: vue/no-computed-properties-in-data | ||
description: disallow accessing computed properties in `data`. | ||
--- | ||
# vue/no-computed-properties-in-data | ||
|
||
> disallow accessing computed properties in `data`. | ||
- :exclamation: <badge text="This rule has not been released yet." vertical="middle" type="error"> ***This rule has not been released yet.*** </badge> | ||
|
||
## :book: Rule Details | ||
|
||
This rule disallow accessing computed properties in `data()`. | ||
The computed property cannot be accessed in `data()` because is before initialization. | ||
|
||
<eslint-code-block :rules="{'vue/no-computed-properties-in-data': ['error']}"> | ||
|
||
```vue | ||
<script> | ||
export default { | ||
data() { | ||
return { | ||
/* ✗ BAD */ | ||
bar: this.foo | ||
} | ||
}, | ||
computed: { | ||
foo () {} | ||
} | ||
} | ||
</script> | ||
``` | ||
|
||
</eslint-code-block> | ||
|
||
## :wrench: Options | ||
|
||
Nothing. | ||
|
||
## :mag: Implementation | ||
|
||
- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-computed-properties-in-data.js) | ||
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-computed-properties-in-data.js) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
/** | ||
* @author Yosuke Ota | ||
* See LICENSE file in root directory for full license. | ||
*/ | ||
'use strict' | ||
|
||
// ------------------------------------------------------------------------------ | ||
// Requirements | ||
// ------------------------------------------------------------------------------ | ||
|
||
const utils = require('../utils') | ||
|
||
/** | ||
* @typedef {import('../utils').VueObjectData} VueObjectData | ||
*/ | ||
|
||
// ------------------------------------------------------------------------------ | ||
// Rule Definition | ||
// ------------------------------------------------------------------------------ | ||
|
||
module.exports = { | ||
meta: { | ||
type: 'problem', | ||
docs: { | ||
description: 'disallow accessing computed properties in `data`.', | ||
categories: undefined, | ||
url: 'https://eslint.vuejs.org/rules/no-computed-properties-in-data.html' | ||
}, | ||
fixable: null, | ||
schema: [], | ||
messages: { | ||
cannotBeUsed: | ||
'The computed property cannot be used in `data()` because it is before initialization.' | ||
} | ||
}, | ||
/** @param {RuleContext} context */ | ||
create(context) { | ||
/** @type {Map<ObjectExpression, {data: FunctionExpression | ArrowFunctionExpression, computedNames:Set<string>}>} */ | ||
const contextMap = new Map() | ||
|
||
/** | ||
* @typedef {object} ScopeStack | ||
* @property {ScopeStack | null} upper | ||
* @property {FunctionExpression | FunctionDeclaration | ArrowFunctionExpression} node | ||
*/ | ||
/** @type {ScopeStack | null} */ | ||
let scopeStack = null | ||
|
||
return utils.compositingVisitors( | ||
{ | ||
/** | ||
* @param {FunctionExpression | FunctionDeclaration | ArrowFunctionExpression} node | ||
*/ | ||
':function'(node) { | ||
scopeStack = { | ||
upper: scopeStack, | ||
node | ||
} | ||
}, | ||
':function:exit'() { | ||
scopeStack = scopeStack && scopeStack.upper | ||
} | ||
}, | ||
utils.defineVueVisitor(context, { | ||
onVueObjectEnter(node) { | ||
const dataProperty = utils.findProperty(node, 'data') | ||
if ( | ||
!dataProperty || | ||
(dataProperty.value.type !== 'FunctionExpression' && | ||
dataProperty.value.type !== 'ArrowFunctionExpression') | ||
) { | ||
return | ||
} | ||
const computedNames = new Set() | ||
for (const computed of utils.iterateProperties( | ||
node, | ||
new Set(['computed']) | ||
)) { | ||
computedNames.add(computed.name) | ||
} | ||
|
||
contextMap.set(node, { data: dataProperty.value, computedNames }) | ||
}, | ||
/** | ||
* @param {MemberExpression} node | ||
* @param {VueObjectData} vueData | ||
*/ | ||
MemberExpression(node, vueData) { | ||
if (!scopeStack || !utils.isThis(node.object, context)) { | ||
return | ||
} | ||
const ctx = contextMap.get(vueData.node) | ||
if (!ctx || ctx.data !== scopeStack.node) { | ||
return | ||
} | ||
const name = utils.getStaticPropertyName(node) | ||
if (!name || !ctx.computedNames.has(name)) { | ||
return | ||
} | ||
context.report({ | ||
node, | ||
messageId: 'cannotBeUsed' | ||
}) | ||
} | ||
}) | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
/** | ||
* @author Yosuke Ota | ||
* See LICENSE file in root directory for full license. | ||
*/ | ||
'use strict' | ||
|
||
const RuleTester = require('eslint').RuleTester | ||
const rule = require('../../../lib/rules/no-computed-properties-in-data') | ||
|
||
const tester = new RuleTester({ | ||
parser: require.resolve('vue-eslint-parser'), | ||
parserOptions: { | ||
ecmaVersion: 2020, | ||
sourceType: 'module' | ||
} | ||
}) | ||
|
||
tester.run('no-computed-properties-in-data', rule, { | ||
valid: [ | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
<script> | ||
export default { | ||
data() { | ||
const foo = this.foo | ||
return {} | ||
} | ||
} | ||
</script> | ||
` | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
<script> | ||
export default { | ||
data() { | ||
const foo = this.foo() | ||
return {} | ||
}, | ||
methods: { | ||
foo() {} | ||
} | ||
} | ||
</script> | ||
` | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
<script> | ||
export default { | ||
props: ['foo'], | ||
data() { | ||
const foo = this.foo | ||
return {} | ||
}, | ||
} | ||
</script> | ||
` | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
<script> | ||
export default { | ||
data: { | ||
foo: this.foo | ||
}, | ||
computed: { | ||
foo () {} | ||
} | ||
} | ||
</script> | ||
` | ||
} | ||
], | ||
invalid: [ | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
<script> | ||
export default { | ||
data() { | ||
const foo = this.foo | ||
return {} | ||
}, | ||
computed: { | ||
foo () {} | ||
} | ||
} | ||
</script> | ||
`, | ||
errors: [ | ||
{ | ||
message: | ||
'The computed property cannot be used in `data()` because it is before initialization.', | ||
line: 5, | ||
column: 23 | ||
} | ||
] | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
<script> | ||
export default { | ||
data() { | ||
const vm = this | ||
const foo = vm.foo | ||
return {} | ||
}, | ||
computed: { | ||
foo () {} | ||
} | ||
} | ||
</script> | ||
`, | ||
errors: [ | ||
{ | ||
message: | ||
'The computed property cannot be used in `data()` because it is before initialization.', | ||
line: 6, | ||
column: 23 | ||
} | ||
] | ||
} | ||
] | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters