diff --git a/docs/rules/README.md b/docs/rules/README.md
index 7e0b1dd96..6e9102682 100644
--- a/docs/rules/README.md
+++ b/docs/rules/README.md
@@ -335,6 +335,8 @@ The following rules extend the rules provided by ESLint itself and apply them to
| [vue/key-spacing](./key-spacing.md) | enforce consistent spacing between keys and values in object literal properties | :wrench: |
| [vue/keyword-spacing](./keyword-spacing.md) | enforce consistent spacing before and after keywords | :wrench: |
| [vue/max-len](./max-len.md) | enforce a maximum line length | |
+| [vue/no-boolean-default](./no-boolean-default.md) | disallow boolean defaults | :wrench: |
+| [vue/no-computed-in-data](./no-computed-in-data.md) | disallow computed properties used in the data property | |
| [vue/no-empty-pattern](./no-empty-pattern.md) | disallow empty destructuring patterns | |
| [vue/no-extra-parens](./no-extra-parens.md) | disallow unnecessary parentheses | :wrench: |
| [vue/no-irregular-whitespace](./no-irregular-whitespace.md) | disallow irregular whitespace | |
diff --git a/docs/rules/no-computed-in-data.md b/docs/rules/no-computed-in-data.md
new file mode 100644
index 000000000..2965d2e8f
--- /dev/null
+++ b/docs/rules/no-computed-in-data.md
@@ -0,0 +1,55 @@
+---
+pageClass: rule-details
+sidebarDepth: 0
+title: vue/no-computed-in-data
+description: disallow computed properties used in the data property
+---
+# vue/no-computed-in-data
+> disallow computed properties used in the data property
+
+## :book: Rule Details
+
+This rule report computed properties that used in data property
+
+
+
+```vue
+
+```
+
+
+
+## :wrench: Options
+
+Nothing.
+
+## :books: Further reading
+
+[Computed Properties](https://vuejs.org/v2/guide/computed.html#Computed-Caching-vs-Methods)
+
+## :mag: Implementation
+
+- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-computed-in-data.js)
+- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-computed-in-data.js)
diff --git a/lib/index.js b/lib/index.js
index 5f285be69..2af7ccfc9 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -48,6 +48,7 @@ module.exports = {
'no-async-in-computed-properties': require('./rules/no-async-in-computed-properties'),
'no-bare-strings-in-template': require('./rules/no-bare-strings-in-template'),
'no-boolean-default': require('./rules/no-boolean-default'),
+ 'no-computed-in-data': require('./rules/no-computed-in-data'),
'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'),
diff --git a/lib/rules/no-computed-in-data.js b/lib/rules/no-computed-in-data.js
new file mode 100644
index 000000000..ae9b76efd
--- /dev/null
+++ b/lib/rules/no-computed-in-data.js
@@ -0,0 +1,105 @@
+/**
+ * @fileoverview Ensure computed properties are not used in the data()
+ * @author IWANABETHATGUY
+ */
+'use strict'
+
+// ------------------------------------------------------------------------------
+// Rule Definition
+// ------------------------------------------------------------------------------
+const utils = require('../utils')
+function topOfStack (stack) {
+ console.assert(Array.isArray(stack))
+ return stack[stack.length - 1]
+}
+module.exports = {
+ meta: {
+ type: 'problem',
+ docs: {
+ description: 'disallow computed properties used in the data property',
+ categories: undefined,
+ recommended: false,
+ url: 'https://eslint.vuejs.org/rules/no-computed-in-data.html'
+ },
+ fixable: null, // or "code" or "whitespace"
+ schema: [
+ // fill in your schema
+ ]
+ },
+
+ create: function (context) {
+ let dataAstNode
+ let targetObjectExpression
+ const memberExpressionMap = Object.create(null)
+ const scopeStack = []
+ // if data is a function, should reference its scope, other wise should be undefined
+ let dataPropertyScope
+ return {
+
+ ObjectExpression (node) {
+ if (!dataAstNode) {
+ dataAstNode = node.properties.find(
+ p =>
+ p.type === 'Property' &&
+ p.key.type === 'Identifier' &&
+ p.key.name === 'data'
+ )
+ if (dataAstNode) {
+ targetObjectExpression = node
+ if (dataAstNode.value.type === 'FunctionExpression') {
+ dataPropertyScope = dataAstNode.value
+ scopeStack.push(dataPropertyScope)
+ }
+ }
+ }
+ },
+ ':function' (node) {
+ scopeStack.push(node)
+ },
+ ':function:exit' (node) {
+ scopeStack.pop()
+ },
+ 'Property:exit' (node) {
+ if (node === dataAstNode) {
+ dataAstNode = undefined
+ }
+ },
+ MemberExpression (node) {
+ if (dataAstNode && dataPropertyScope === topOfStack(scopeStack)) {
+ // a memberExpression `like this.a.c.d` -> when traverse to c.d we can got the the full name -> this.a.c.d
+ const fullName = utils.parseMemberExpression(node).slice(0, 2).join('.')
+ if (memberExpressionMap[fullName]) {
+ // check if parent node in this array, if true ignore this node, such as `{a: this.a.c.d}`, this traverse function visit order is `this.a.c.d` -> `a.c.d` -> `c.d`
+ const hasParentNodeInArray = memberExpressionMap[fullName].some(nodeInMap => node.parent === nodeInMap)
+ if (!hasParentNodeInArray) {
+ memberExpressionMap[fullName] = [...memberExpressionMap[fullName], node]
+ }
+ } else {
+ memberExpressionMap[fullName] = [node]
+ }
+ }
+ },
+ ...utils.executeOnVue(context, obj => {
+ // check if targetObjectExpression is Vue component
+ if (targetObjectExpression !== obj) {
+ return
+ }
+ const computedPropertyNameList = utils.getComputedProperties(obj).map(item => `this.${item.key}`)
+ Object.keys(memberExpressionMap).forEach(fullName => {
+ const index = computedPropertyNameList.findIndex(name => fullName.startsWith(name))
+ if (index !== -1) {
+ memberExpressionMap[fullName].forEach(memberExpressionNode => {
+ context.report({
+ node: memberExpressionNode,
+ message: `Computed property '{{name}}' can't use in data property.`,
+ data: {
+ name: computedPropertyNameList[index]
+ }
+ })
+ })
+ }
+ })
+ })
+ }
+ }
+}
diff --git a/tests/lib/rules/no-computed-in-data.js b/tests/lib/rules/no-computed-in-data.js
new file mode 100644
index 000000000..a555cd525
--- /dev/null
+++ b/tests/lib/rules/no-computed-in-data.js
@@ -0,0 +1,271 @@
+/**
+ * @fileoverview Ensure computed properties are not used in the data()
+ * @author IWANABETHATGUY
+ */
+'use strict'
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require('../../../lib/rules/no-computed-in-data')
+
+var RuleTester = require('eslint').RuleTester
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+var ruleTester = new RuleTester({
+ parser: require.resolve('vue-eslint-parser'),
+ parserOptions: {
+ ecmaVersion: 2019,
+ sourceType: 'module'
+ }
+})
+ruleTester.run('no-computed-in-data', rule, {
+
+ valid: [
+ {
+ filename: 'test.vue',
+ code: `
+
+ `
+ },
+ // should not warn when use computed in methods
+ {
+ filename: 'test.vue',
+ code: `
+
+ `
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+ `
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+ `
+ },
+ // should not warn when objectExpression is not a vue component
+ {
+ filename: 'test.vue',
+ code: `
+
+ `
+ }
+ ],
+ invalid: [
+ // should warn when prop key is an String literal
+ {
+ filename: 'test.vue',
+ code: `
+
+ `,
+ errors: [
+ `Computed property 'this.test' can't use in data property.`,
+ `Computed property 'this.foo' can't use in data property.`
+ ]
+ },
+ // should report when data is objectExpression, when this is a root component
+ {
+ filename: 'test.vue',
+ code: `
+
+ `,
+ errors: [
+ `Computed property 'this.test' can't use in data property.`
+ ]
+ },
+ // same computed data referenced by multi data property
+ {
+ filename: 'test.vue',
+ code: `
+
+ `,
+ errors: [
+ {
+ message: `Computed property 'this.test' can't use in data property.`,
+ line: 6,
+ column: 16
+ },
+ {
+ message: `Computed property 'this.test' can't use in data property.`,
+ line: 7,
+ column: 16
+ }
+ ]
+ },
+ // should also report when computed data return an object
+ {
+ filename: 'test.vue',
+ code: `
+
+ `,
+ errors: [
+ {
+ message: `Computed property 'this.test' can't use in data property.`,
+ line: 6,
+ column: 16,
+ endColumn: 29,
+ endLine: 6
+ },
+ {
+ message: `Computed property 'this.test' can't use in data property.`,
+ line: 7,
+ column: 16,
+ endLine: 7,
+ endColumn: 29
+ }
+ ]
+ },
+ // should only report the data function scope computed property
+ {
+ filename: 'test.vue',
+ code: `
+
+ `,
+ errors: [
+ {
+ message: `Computed property 'this.foo' can't use in data property.`,
+ line: 6,
+ column: 18,
+ endColumn: 26,
+ endLine: 6
+ }
+ ]
+ }
+ ]
+})