Skip to content

Commit 7bb9f5e

Browse files
committed
Clarify emitted events examples and guidance
1 parent 18dce97 commit 7bb9f5e

File tree

1 file changed

+48
-18
lines changed

1 file changed

+48
-18
lines changed

src/style-guide/rules-essential.md

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -107,51 +107,81 @@ Treat emitted events as part of a component's public contract, and declare them
107107
Explicit [event declarations](/guide/components/events) document how a component communicates outward and make parent-child interactions easier to follow.
108108
:::
109109

110+
In standard `setup()` usage, declare events with the [`emits`](/guide/components/events#declaring-emitted-events) option. In [`<script setup>`](/api/sfc-script-setup#defineprops-defineemits), declare them with `defineEmits()`.
111+
112+
Use the object syntax when event payloads need validation, and an array of event names when they do not.
113+
114+
In TypeScript, prefer a typed `defineEmits()` declaration so the event contract is checked by the type system as well as documented in the component. In Vue 3.3+, the named tuple syntax is usually the more succinct form.
115+
110116
<div class="style-example style-example-bad">
111117
<h3>Bad</h3>
112118

113-
```js
114-
function submit() {
115-
$emit('submit', { email: form.email })
119+
```vue
120+
<script>
121+
export default {
122+
setup(props, { emit }) {
123+
function submit(email) {
124+
emit('submit', { email })
125+
}
126+
127+
return { submit }
128+
}
116129
}
130+
</script>
117131
```
118132

119133
</div>
120134

121135
<div class="style-example style-example-good">
122136
<h3>Good</h3>
123137

124-
```js
138+
```vue
139+
<script>
140+
export default {
141+
emits: {
142+
submit: (payload) => typeof payload?.email === 'string'
143+
},
144+
145+
setup(props, { emit }) {
146+
function submit(email) {
147+
emit('submit', { email })
148+
}
149+
150+
return { submit }
151+
}
152+
}
153+
</script>
154+
```
155+
156+
```vue
157+
<script setup>
125158
const emit = defineEmits({
126159
submit: (payload) => typeof payload?.email === 'string'
127160
})
128161
129-
function submit() {
130-
emit('submit', { email: form.email })
162+
function submit(email) {
163+
emit('submit', { email })
131164
}
165+
</script>
132166
```
133167

134-
```ts
168+
```vue
169+
<script setup lang="ts">
135170
const emit = defineEmits<{
136-
// type-based definition
171+
// Type-based declaration
137172
(e: 'submit', payload: { email: string }): void
138-
// 3.3+: alternative, more succinct syntax
139-
submit: [payload, { email: string}]
173+
// Vue 3.3+: alternative, more succinct syntax
174+
submit: [payload: { email: string }]
140175
}>()
141176
142-
function submit() {
143-
emit('submit', { email: form.email })
177+
function submit(email: string) {
178+
emit('submit', { email })
144179
}
180+
</script>
145181
```
146182

147183
</div>
148184

149-
**Notes**
150-
151-
- An array of event names is acceptable when payload validation would add no real value.
152-
- In TypeScript, prefer a typed `defineEmits()` declaration so the event contract is checked by the type system as well as documented in the component.
153-
- If runtime payload validation is also useful, use the object syntax.
154-
155185
## Keep parent-child data flow explicit {#keep-parent-child-data-flow-explicit}
156186

157187
Pass data down with props, and communicate requested changes back up with emitted events.

0 commit comments

Comments
 (0)