Skip to content

Commit

Permalink
Add vue/require-explicit-emits rule
Browse files Browse the repository at this point in the history
  • Loading branch information
ota-meshi committed May 13, 2020
1 parent b2dc044 commit b9c282e
Show file tree
Hide file tree
Showing 8 changed files with 1,989 additions and 14 deletions.
1 change: 1 addition & 0 deletions docs/rules/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ For example:
| [vue/object-curly-spacing](./object-curly-spacing.md) | enforce consistent spacing inside braces | :wrench: |
| [vue/padding-line-between-blocks](./padding-line-between-blocks.md) | require or disallow padding lines between blocks | :wrench: |
| [vue/require-direct-export](./require-direct-export.md) | require the component to be directly exported | |
| [vue/require-explicit-emits](./require-explicit-emits.md) | require `emits` option with name triggered by `$emit()` | |
| [vue/require-name-property](./require-name-property.md) | require a name property in Vue components | |
| [vue/script-indent](./script-indent.md) | enforce consistent indentation in `<script>` | :wrench: |
| [vue/sort-keys](./sort-keys.md) | enforce sort-keys in a manner that is compatible with order-in-components | |
Expand Down
10 changes: 6 additions & 4 deletions docs/rules/no-deprecated-vue-config-keycodes.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ description: disallow using deprecated `Vue.config.keyCodes` (in Vue.js 3.0.0+)

This rule reports use of deprecated `Vue.config.keyCodes` (in Vue.js 3.0.0+)

<eslint-code-block filename="a.js" language="javascript ":rules="{'vue/no-deprecated-vue-config-keycodes': ['error']}">
<eslint-code-block filename="a.js" language="javascript" :rules="{'vue/no-deprecated-vue-config-keycodes': ['error']}">

```js
/* ✗ BAD */
Expand All @@ -31,14 +31,16 @@ Nothing.
## :couple: Related rules

- [vue/no-deprecated-v-on-number-modifiers]
- [API - Global Config - keyCodes]

[vue/no-deprecated-v-on-number-modifiers]: ./no-deprecated-v-on-number-modifiers.md
[API - Global Config - keyCodes]: https://vuejs.org/v2/api/#keyCodes

## :books: Further reading

- [Vue RFCs - 0014-drop-keycode-support](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0014-drop-keycode-support.md)
- [Vue RFCs - 0014-drop-keycode-support]
- [API - Global Config - keyCodes]

[Vue RFCs - 0014-drop-keycode-support]: https://github.com/vuejs/rfcs/blob/master/active-rfcs/0014-drop-keycode-support.md
[API - Global Config - keyCodes]: https://vuejs.org/v2/api/#keyCodes

## :mag: Implementation

Expand Down
84 changes: 84 additions & 0 deletions docs/rules/require-explicit-emits.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
---
pageClass: rule-details
sidebarDepth: 0
title: vue/require-explicit-emits
description: require `emits` option with name triggered by `$emit()`
---
# vue/require-explicit-emits
> require `emits` option with name triggered by `$emit()`
## :book: Rule Details

This rule reports event triggers not declared with the `emits` option. (The `emits` option is a new in Vue.js 3.0.0+)

Explicit `emits` declaration serves as self-documenting code. This can be useful for other developers to instantly understand what events the component is supposed to emit.
Also, with attribute fallthrough changes in Vue.js 3.0.0+, `v-on` listeners on components will fallthrough as native listeners by default. Declare it as a component-only event in `emits` to avoid unnecessary registration of native listeners.

<eslint-code-block :rules="{'vue/require-explicit-emits': ['error']}">

```vue
<template>
<!-- ✓ GOOD -->
<div @click="$emit('good')"/>
<!-- ✗ BAD -->
<div @click="$emit('bad')"/>
</template>
<script>
export default {
emits: ['good']
}
</script>
```

</eslint-code-block>

<eslint-code-block :rules="{'vue/require-explicit-emits': ['error']}">

```vue
<script>
export default {
emits: ['good'],
methods: {
foo () {
// ✓ GOOD
this.$emit('good')
// ✗ BAD
this.$emit('bad')
}
}
}
</script>
```

</eslint-code-block>

<eslint-code-block :rules="{'vue/require-explicit-emits': ['error']}">

```vue
<script>
export default {
emits: ['good'],
setup (props, context) {
// ✓ GOOD
context.emit('good')
// ✗ BAD
context.emit('bad')
}
}
</script>
```

</eslint-code-block>

## :wrench: Options

Nothing.

## :books: Further reading

- [Vue RFCs - 0030-emits-option](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0030-emits-option.md)

## :mag: Implementation

- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/require-explicit-emits.js)
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/require-explicit-emits.js)
1 change: 1 addition & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ module.exports = {
'require-component-is': require('./rules/require-component-is'),
'require-default-prop': require('./rules/require-default-prop'),
'require-direct-export': require('./rules/require-direct-export'),
'require-explicit-emits': require('./rules/require-explicit-emits'),
'require-name-property': require('./rules/require-name-property'),
'require-prop-type-constructor': require('./rules/require-prop-type-constructor'),
'require-prop-types': require('./rules/require-prop-types'),
Expand Down
3 changes: 2 additions & 1 deletion lib/rules/no-setup-props-destructure.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ module.exports = {
':function' (node) {
scopeStack = { upper: scopeStack, functionNode: node }
},
':function>*' (node) {
':function > Identifier' (node) {
// find `setup(*props*)`
const setupFunctionData = setupFunctions.get(node.parent)
if (!setupFunctionData || setupFunctionData.propsParam !== node) {
return
Expand Down
Loading

0 comments on commit b9c282e

Please sign in to comment.