Skip to content

Add rule vue/no-early-return #1889

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/rules/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ For example:
| [vue/no-bare-strings-in-template](./no-bare-strings-in-template.md) | disallow the use of bare strings in `<template>` | | :hammer: |
| [vue/no-boolean-default](./no-boolean-default.md) | disallow boolean defaults | :wrench: | :hammer: |
| [vue/no-duplicate-attr-inheritance](./no-duplicate-attr-inheritance.md) | enforce `inheritAttrs` to be set to `false` when using `v-bind="$attrs"` | | :hammer: |
| [vue/no-early-return](./no-early-return.md) | disallow early returns in setup and data functions | | :warning: |
| [vue/no-empty-component-block](./no-empty-component-block.md) | disallow the `<template>` `<script>` `<style>` block to be empty | | :hammer: |
| [vue/no-multiple-objects-in-class](./no-multiple-objects-in-class.md) | disallow to pass multiple objects into array to class | | :hammer: |
| [vue/no-potential-component-option-typo](./no-potential-component-option-typo.md) | disallow a potential typo in your component property | :bulb: | :hammer: |
Expand Down
103 changes: 103 additions & 0 deletions docs/rules/no-early-return.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
---
pageClass: rule-details
sidebarDepth: 0
title: vue/no-early-return
description: disallow early returns in setup and data functions
---
# vue/no-early-return

> disallow early returns in setup and data functions

- :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 helps to identify accidental `return` statements in the `setup` block of a Vue component, these are `return` statements that would exit the `setup` block skipping part of the block itself (not allowing to each the end of the block).

On the other hand, the rule checks the `data` block too, applying the same logic.

<eslint-code-block :rules="{'vue/no-early-return': ['error']}">

```vue
<!-- ✓ GOOD -->
<script>
export default {
setup () {
const foo = ref()
return { foo }
}
}
</script>
```

</eslint-code-block>

<eslint-code-block :rules="{'vue/no-early-return': ['error']}">

```vue
<!-- ✗ BAD -->
<script>
export default {
setup () {
const foo = ref()

if (maybe) {
return
}

for (const t of foo.value) {
if (t) {
return
}
}

return { foo }
}
}
</script>
```

</eslint-code-block>

<eslint-code-block :rules="{'vue/no-early-return': ['error']}">

```vue
<!-- ✓ GOOD -->
<script>
export default {
data () {
return { foo: true }
}
}
</script>
```

</eslint-code-block>

<eslint-code-block :rules="{'vue/no-early-return': ['error']}">

```vue
<!-- ✗ BAD -->
<script>
export default {
data () {
if (maybe) {
return { foo: false }
}

return { foo: true }
}
}
</script>
```

</eslint-code-block>

## :wrench: Options

Nothing.

## :mag: Implementation

- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-early-return.js)
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-early-return.js)
1 change: 1 addition & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ module.exports = {
'no-dupe-v-else-if': require('./rules/no-dupe-v-else-if'),
'no-duplicate-attr-inheritance': require('./rules/no-duplicate-attr-inheritance'),
'no-duplicate-attributes': require('./rules/no-duplicate-attributes'),
'no-early-return': require('./rules/no-early-return'),
'no-empty-component-block': require('./rules/no-empty-component-block'),
'no-empty-pattern': require('./rules/no-empty-pattern'),
'no-export-in-script-setup': require('./rules/no-export-in-script-setup'),
Expand Down
76 changes: 76 additions & 0 deletions lib/rules/no-early-return.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/**
* @author *****your name*****
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fill in your name or username here :)

* See LICENSE file in root directory for full license.
*/
'use strict'

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

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

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

module.exports = {
meta: {
type: 'problem',
docs: {
description: 'disallow early returns in setup and data functions',
categories: undefined,
url: 'https://eslint.vuejs.org/rules/no-early-return.html'
},
fixable: null,
schema: []
},

/** @param {RuleContext} context */
create(context) {
const rStatementLocs = []
return utils.compositingVisitors(
utils.defineVueVisitor(context, {
ReturnStatement(node) {
if (context.getScope().type === 'function') {
return
}
rStatementLocs.push(node.loc)
},

onSetupFunctionExit() {
if (rStatementLocs.length === 0) {
return
}

for (const loc of rStatementLocs) {
context.report({
loc,
message: 'Extra return statement in setup function.'
})
}
},
onVueObjectEnter(node) {
const dataProperty = utils.findProperty(node, 'data')
if (
!dataProperty ||
(dataProperty.value.type !== 'FunctionExpression' &&
dataProperty.value.type !== 'ArrowFunctionExpression')
) {
return
}
if (
context
.getSourceCode()
.ast.tokens.filter((t) => t.value === 'return').length > 1
) {
context.report({
node,
message: 'Extra return statement in data function.'
})
}
}
})
)
}
}
Loading