-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Document changes related to $attrs $listeners and v-on.native (close #526,#592) #608
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
Changes from 4 commits
04f80cb
426b551
f3b66d3
843917e
6f1665d
e329944
4f536ca
f7cceb9
33f0956
eefcb59
1a3bb75
1df13cd
4988139
58b5404
e7b32a3
d533308
2582673
4b6292c
4959543
911c32b
c50eb43
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
--- | ||
title: $attrs includes class & style | ||
badges: | ||
- breaking | ||
--- | ||
|
||
# `$attrs` includes `class` & `style` <MigrationBadges :badges="$frontmatter.badges" /> | ||
|
||
## Overview | ||
|
||
`$attrs` now contains _all_ attributes passed to a component, including `class` and `style`. | ||
|
||
## 2.x Behavior | ||
|
||
`class` and `style` attributes get some special handling in the Vue 2 virtual DOM implementation. For that reason, they are _not_ included in `$attrs`, while all other attributes are. | ||
|
||
A side effect of this manifests when using `inheritAttrs: false`: | ||
|
||
- Attributes in `$attrs` are no longer automatically added to the root element, leaving it to the developer to decide where to add them. | ||
- But `class` and `style`, not being part of `$attrs`, will still be applied to the component's root element: | ||
|
||
```html | ||
<template> | ||
<label> | ||
<input type="text" v-bind="$attrs" /> | ||
</label> | ||
</template> | ||
<script> | ||
export default { | ||
inheritAttrs: false | ||
} | ||
</script> | ||
``` | ||
|
||
when used like this: | ||
|
||
```html | ||
<my-component id="my-id" class="my-class"></my-component> | ||
``` | ||
|
||
...will generate this HTML: | ||
|
||
```html | ||
<label class="my-class"> | ||
<input type="text" id="my-id" /> | ||
</label> | ||
``` | ||
|
||
## 3.x Behavior | ||
|
||
`$attrs` contains _all_ attributes, which makes it easier to apply all of them to a different element. The example from above now generates the following HTML: | ||
|
||
```html | ||
<label> | ||
<input type="text" id="my-id" class="my-class" /> | ||
</label> | ||
``` | ||
|
||
## Migration Strategy | ||
|
||
In components that use `inheritAttrs: false`, make sure that styling still works as intended. If you previously relied on the special behavior of `class` and `style`, some visuals might be broken as these attributes might now be applied to another element. | ||
|
||
## See also | ||
|
||
- [Relevant RFC](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0031-attr-fallthrough.md) | ||
- [Migration guide - `$listeners` removed](/.listeners-removed.md) | ||
- [Migration guide - New Emits Option](/.emits-option.md) | ||
- [Migration guide - `.native` modifier removed](./v-on-native-modifier-removed.md) | ||
- [Migration guide - Changes in the Render Functions API](./render-functions.md) | ||
LinusBorg marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
--- | ||
title: emits Option | ||
badges: | ||
- new | ||
--- | ||
|
||
# `emits` Option <MigrationBadges :badges="$frontmatter.badges" /> | ||
|
||
## Overview | ||
|
||
Vue 3 now offers an `emits` option similar to the existing `props` option. This option can be used to define the events that a component can emit to its parent. | ||
|
||
## 2.x Behavior | ||
|
||
In Vue 2, you can define the props that a component received, but you can't declare which events it can emit: | ||
|
||
```html | ||
<template> | ||
<p>{{ text }}</p> | ||
LinusBorg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
<button v-on:click="$emit('accepted')">OK</button> | ||
</template> | ||
<script> | ||
export default { | ||
props: ['text'] | ||
} | ||
</script> | ||
``` | ||
|
||
## 3.x Behavior | ||
|
||
Similar to props, the events that the component emit can now be defined with the `emits` option. | ||
LinusBorg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```javascript | ||
LinusBorg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
<template> | ||
<p>{{ text }}</p> | ||
<button v-on:click="$emit('accepted')">OK</button> | ||
</template> | ||
<script> | ||
export default { | ||
props: ['text'], | ||
emits: ['accepted'] | ||
} | ||
</script> | ||
``` | ||
|
||
The option also accepts an object notation, which allows the developer to define validators for the arguments that are passed with the emitted event, similar to validators in props definitions. | ||
|
||
For more information on this, please read the [API documentation for this feature](../api/options-data.md#emits). | ||
LinusBorg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## Migration Strategy | ||
|
||
It is highly recommended that you document all of the emitted events of your components this way because of the [removal of the `.native` modifier](./native-modifier-removed.md). | ||
LinusBorg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
All events not defined with `emits` are now added as DOM event listeners to the components root node (unless `inheritAttrs: false` has been set). | ||
LinusBorg marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe component's needs an apostrophe. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand what you mean, but that's not grammatically correct in English, unfortunately. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @sdras. This sentence seems to be grammatically correct to me, aside from the missing apostrophe. It does need the reader to parse it the correct way though, so maybe it should be reworded to make it easier to follow? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The first paragraph speaks about "components", plural. I'm with Sarah that we can't switch to singular in the next paragraph. But doesn't "components'" exist in English? No sure ^^ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Trying to make it plural is going to be tricky as root node is singular. I think the components' root nodes would be confusing as it could be misconstrued as a reference to fragments. Personally, I'd try to make the component singular. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did a little change in wording of the previous sentence to make singular work better. I think it's no at least grammatically correct and gets the point across. |
||
|
||
### Examnple | ||
LinusBorg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
If ou have components that re-emit native events to their parent, this would now lead to two events being fired: | ||
LinusBorg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```html | ||
<template> | ||
<button v-on:click="$emit('click', event)">OK</button> | ||
LinusBorg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
</template> | ||
<script> | ||
export default { | ||
props: ['text'], | ||
LinusBorg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
emits: [] // without declared event | ||
} | ||
</script> | ||
``` | ||
|
||
When a parent listens for the `click` event on the component: | ||
|
||
```html | ||
<my-button v-on:click="handleClick"></my-button> | ||
``` | ||
|
||
it would now be triggered _twice_: | ||
|
||
- Once from `$emit()` | ||
- Once from a native event listener applied to the root element | ||
|
||
Here you have two options: | ||
|
||
1. Properly declare the `click` event. This is useful if you actually do add some logic to that event handler in `<my-button>` | ||
2. remove the re-emitting of the event, since the parent can now listen for the native event easily, without adding `.native`. Suitable when you really only re-emit the event anyway. | ||
LinusBorg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## See also | ||
|
||
- [Relevant RFC](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0030-emits-option.md) | ||
- [Migration guide - `.native` modifier removed](./v-on-native-modifier-removed.md) | ||
- [Migration guide - `$listeners` removed](./listeners-removed.md) | ||
- [Migration guide - `$attrs` includes `class` & `style` ](./attrs-includes-class-style.md) | ||
- [Migration guide - Changes in the Render Functions API](./render-functions.md) | ||
LinusBorg marked this conversation as resolved.
Show resolved
Hide resolved
LinusBorg marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
--- | ||
title: $listeners removed | ||
badges: | ||
- breaking | ||
--- | ||
|
||
# `$listeners` removed <MigrationBadges :badges="$frontmatter.badges" /> | ||
|
||
## Overview | ||
|
||
The `$listeners` object has been removed in Vue 3. Event listeners are now part of `$attrs`. | ||
LinusBorg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```javascript | ||
{ | ||
text: 'this is a prop', | ||
LinusBorg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
onClose: () => console.log('close Event triggered') | ||
} | ||
``` | ||
|
||
## 2.x Syntax | ||
|
||
In Vue 2, you can access attributes passed to your components with `this.$attrs`, and event listeners with `this.$listeners`. | ||
In combination with `inheritAttrs: false`, they allow the developer to apply these attributes and listeners to some other element instead of the root element: | ||
|
||
```html | ||
LinusBorg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
<template> | ||
<label> | ||
<input type="text" v-bind="$attrs" v-on="$listeners" /> | ||
</label> | ||
</template> | ||
<script> | ||
export default { | ||
inheritAttrs: false | ||
} | ||
</script> | ||
``` | ||
|
||
## 3.x Syntax | ||
|
||
In Vue 3's virtual DOM, event listeners are now just attributes, prefixed with `on`, and as such are part of the `$attrs` object, so `$listeners` has been removed. | ||
|
||
```html | ||
<template> | ||
<label> | ||
<input type="text" v-bind="$attrs" /> | ||
</label> | ||
</template> | ||
<script> | ||
export default { | ||
inheritAttrs: false | ||
} | ||
</script> | ||
``` | ||
|
||
If this component received an `id` attribute and a `v-on:close` listener, the `$attrs` object will now look like this: | ||
|
||
```javascript | ||
{ | ||
id: 'my-input', | ||
onClose: () => console.log('close Event triggered') | ||
} | ||
``` | ||
|
||
## Migration Strategy | ||
|
||
Remove all usages of `$listeners`. | ||
|
||
## See also | ||
|
||
- [Relevant RFC](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0031-attr-fallthrough.md) | ||
- [Migration guide - `$attrs`includes `class` & `style` ](./attrs-included-class-style.md) | ||
LinusBorg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
- [Migration guide - Changes in the Render Functions API](./render-functions.md) | ||
- [Migration guide - New Emits Option](/.emits-option.md) | ||
- [Migration guide - `.native` modifier removed](./v-on-native-modifier-removed.md) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
--- | ||
title: v-on.native modifier removed | ||
badges: | ||
- breaking | ||
--- | ||
|
||
# `v-on.native` modifier removed <MigrationBadges :badges="$frontmatter.badges" /> | ||
|
||
## Overview | ||
|
||
The `.native` modifier for `v-on` has been removed. | ||
|
||
## 2.x Syntax | ||
|
||
Event listeners passed to a component with `v-on` are by default only triggered by emitting an event with `this.$emit`. To add a native DOM listener to the child component's root element instead, the `.native` modifier can be used: | ||
|
||
```html | ||
<my-component | ||
v-on:close="handleComponentEvent" | ||
v-on:click.native="handleNativeClickEvent" | ||
/> | ||
``` | ||
|
||
## 3.x Syntax | ||
|
||
The `.native` modifier for `v-on` has been removed. At the same time, the [new `emits` option](/.emits-option.md) allows the child to define which events it does indeed emit. | ||
LinusBorg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Consequently, Vue will now add all event listeners that are _not_ defined as component-emitted events in the child as native event listeners to the child's root element (unless `inheritAttrs: false`)has been set in the child's options). | ||
LinusBorg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```html | ||
<my-component | ||
v-on:close="handleComponentEvent" | ||
v-on:click="handleNativeClickEvent" | ||
/> | ||
``` | ||
|
||
`MyComponent.vue` | ||
|
||
```html | ||
<script> | ||
export default { | ||
emits: ['close'] | ||
} | ||
</script> | ||
``` | ||
|
||
## Migration Strategy | ||
|
||
- remove all instances of the `.native` modifier. | ||
- ensure that all your components document their events with the `emits` option. | ||
|
||
## See also | ||
|
||
- [Relevant RFC](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0031-attr-fallthrough.md#v-on-listener-fallthrough) | ||
- [Migration guide - New Emits Option](/.emits-option.md) | ||
- [Migration guide - `$listeners` removed](/.listeners-removed.md) | ||
- [Migration guide - Changes in the Render Functions API](./render-functions.md) | ||
LinusBorg marked this conversation as resolved.
Show resolved
Hide resolved
|
Uh oh!
There was an error while loading. Please reload this page.