Skip to content

Commit b9c282e

Browse files
committed
Add vue/require-explicit-emits rule
1 parent b2dc044 commit b9c282e

8 files changed

+1989
-14
lines changed

Diff for: docs/rules/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ For example:
286286
| [vue/object-curly-spacing](./object-curly-spacing.md) | enforce consistent spacing inside braces | :wrench: |
287287
| [vue/padding-line-between-blocks](./padding-line-between-blocks.md) | require or disallow padding lines between blocks | :wrench: |
288288
| [vue/require-direct-export](./require-direct-export.md) | require the component to be directly exported | |
289+
| [vue/require-explicit-emits](./require-explicit-emits.md) | require `emits` option with name triggered by `$emit()` | |
289290
| [vue/require-name-property](./require-name-property.md) | require a name property in Vue components | |
290291
| [vue/script-indent](./script-indent.md) | enforce consistent indentation in `<script>` | :wrench: |
291292
| [vue/sort-keys](./sort-keys.md) | enforce sort-keys in a manner that is compatible with order-in-components | |

Diff for: docs/rules/no-deprecated-vue-config-keycodes.md

+6-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ description: disallow using deprecated `Vue.config.keyCodes` (in Vue.js 3.0.0+)
1313

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

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

1818
```js
1919
/* ✗ BAD */
@@ -31,14 +31,16 @@ Nothing.
3131
## :couple: Related rules
3232

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

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

3937
## :books: Further reading
4038

41-
- [Vue RFCs - 0014-drop-keycode-support](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0014-drop-keycode-support.md)
39+
- [Vue RFCs - 0014-drop-keycode-support]
40+
- [API - Global Config - keyCodes]
41+
42+
[Vue RFCs - 0014-drop-keycode-support]: https://github.com/vuejs/rfcs/blob/master/active-rfcs/0014-drop-keycode-support.md
43+
[API - Global Config - keyCodes]: https://vuejs.org/v2/api/#keyCodes
4244

4345
## :mag: Implementation
4446

Diff for: docs/rules/require-explicit-emits.md

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
---
2+
pageClass: rule-details
3+
sidebarDepth: 0
4+
title: vue/require-explicit-emits
5+
description: require `emits` option with name triggered by `$emit()`
6+
---
7+
# vue/require-explicit-emits
8+
> require `emits` option with name triggered by `$emit()`
9+
10+
## :book: Rule Details
11+
12+
This rule reports event triggers not declared with the `emits` option. (The `emits` option is a new in Vue.js 3.0.0+)
13+
14+
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.
15+
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.
16+
17+
<eslint-code-block :rules="{'vue/require-explicit-emits': ['error']}">
18+
19+
```vue
20+
<template>
21+
<!-- ✓ GOOD -->
22+
<div @click="$emit('good')"/>
23+
<!-- ✗ BAD -->
24+
<div @click="$emit('bad')"/>
25+
</template>
26+
<script>
27+
export default {
28+
emits: ['good']
29+
}
30+
</script>
31+
```
32+
33+
</eslint-code-block>
34+
35+
<eslint-code-block :rules="{'vue/require-explicit-emits': ['error']}">
36+
37+
```vue
38+
<script>
39+
export default {
40+
emits: ['good'],
41+
methods: {
42+
foo () {
43+
// ✓ GOOD
44+
this.$emit('good')
45+
// ✗ BAD
46+
this.$emit('bad')
47+
}
48+
}
49+
}
50+
</script>
51+
```
52+
53+
</eslint-code-block>
54+
55+
<eslint-code-block :rules="{'vue/require-explicit-emits': ['error']}">
56+
57+
```vue
58+
<script>
59+
export default {
60+
emits: ['good'],
61+
setup (props, context) {
62+
// ✓ GOOD
63+
context.emit('good')
64+
// ✗ BAD
65+
context.emit('bad')
66+
}
67+
}
68+
</script>
69+
```
70+
71+
</eslint-code-block>
72+
73+
## :wrench: Options
74+
75+
Nothing.
76+
77+
## :books: Further reading
78+
79+
- [Vue RFCs - 0030-emits-option](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0030-emits-option.md)
80+
81+
## :mag: Implementation
82+
83+
- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/require-explicit-emits.js)
84+
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/require-explicit-emits.js)

Diff for: lib/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ module.exports = {
8787
'require-component-is': require('./rules/require-component-is'),
8888
'require-default-prop': require('./rules/require-default-prop'),
8989
'require-direct-export': require('./rules/require-direct-export'),
90+
'require-explicit-emits': require('./rules/require-explicit-emits'),
9091
'require-name-property': require('./rules/require-name-property'),
9192
'require-prop-type-constructor': require('./rules/require-prop-type-constructor'),
9293
'require-prop-types': require('./rules/require-prop-types'),

Diff for: lib/rules/no-setup-props-destructure.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ module.exports = {
8383
':function' (node) {
8484
scopeStack = { upper: scopeStack, functionNode: node }
8585
},
86-
':function>*' (node) {
86+
':function > Identifier' (node) {
87+
// find `setup(*props*)`
8788
const setupFunctionData = setupFunctions.get(node.parent)
8889
if (!setupFunctionData || setupFunctionData.propsParam !== node) {
8990
return

0 commit comments

Comments
 (0)