Skip to content

Commit d3af36c

Browse files
LinusBorgThorsten Luenborgskirtles-code
authored
Document changes related to $attrs $listeners and v-on.native (close #526,#592) (#608)
* feat: Add migration guide for 3 changes: - $listeners removed - v-on.native modifier removed - new emits option * feat: document $attrs new behaviour now includes class and style behaviour. * fix: typos, grammar and language improvements * more fixes * Update src/guide/migration/emits-option.md * Update src/guide/migration/introduction.md fix broken link * Update src/guide/migration/listeners-removed.md fix broken link Co-authored-by: skirtle <[email protected]> * Update src/guide/migration/introduction.md fix broken link Co-authored-by: skirtle <[email protected]> * Update src/guide/migration/emits-option.md typo * Update src/guide/migration/listeners-removed.md grammar * Update src/guide/migration/listeners-removed.md wording * Update src/guide/migration/v-on-native-modifier-removed.md * Update src/guide/migration/emits-option.md fix broken link * Update src/guide/migration/introduction.md fix broken link * still more mistakes to fix. * fix link to api docs for "emits:" * use vue instead of html as hightligh lang where possible * fix broken link * fix missing template content * wording/grammar Co-authored-by: Thorsten Luenborg <[email protected]> Co-authored-by: skirtle <[email protected]>
1 parent a636299 commit d3af36c

File tree

6 files changed

+305
-0
lines changed

6 files changed

+305
-0
lines changed

src/.vuepress/config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,11 @@ const sidebar = {
120120
'/guide/migration/array-refs',
121121
'/guide/migration/async-components',
122122
'/guide/migration/attribute-coercion',
123+
'/guide/migration/attrs-includes-class-style',
123124
'/guide/migration/custom-directives',
124125
'/guide/migration/custom-elements-interop',
125126
'/guide/migration/data-option',
127+
'/guide/migration/emits-option',
126128
'/guide/migration/events-api',
127129
'/guide/migration/filters',
128130
'/guide/migration/fragments',
@@ -132,10 +134,12 @@ const sidebar = {
132134
'/guide/migration/inline-template-attribute',
133135
'/guide/migration/key-attribute',
134136
'/guide/migration/keycode-modifiers',
137+
'/guide/migration/listeners-removed',
135138
'/guide/migration/props-default-this',
136139
'/guide/migration/render-function-api',
137140
'/guide/migration/slots-unification',
138141
'/guide/migration/transition',
142+
'/guide/migration/v-on-native-modifier-removed',
139143
'/guide/migration/v-model',
140144
'/guide/migration/v-if-v-for',
141145
'/guide/migration/v-bind'
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
---
2+
title: $attrs includes class & style
3+
badges:
4+
- breaking
5+
---
6+
7+
# `$attrs` includes `class` & `style` <MigrationBadges :badges="$frontmatter.badges" />
8+
9+
## Overview
10+
11+
`$attrs` now contains _all_ attributes passed to a component, including `class` and `style`.
12+
13+
## 2.x Behavior
14+
15+
`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.
16+
17+
A side effect of this manifests when using `inheritAttrs: false`:
18+
19+
- Attributes in `$attrs` are no longer automatically added to the root element, leaving it to the developer to decide where to add them.
20+
- But `class` and `style`, not being part of `$attrs`, will still be applied to the component's root element:
21+
22+
```vue
23+
<template>
24+
<label>
25+
<input type="text" v-bind="$attrs" />
26+
</label>
27+
</template>
28+
<script>
29+
export default {
30+
inheritAttrs: false
31+
}
32+
</script>
33+
```
34+
35+
when used like this:
36+
37+
```html
38+
<my-component id="my-id" class="my-class"></my-component>
39+
```
40+
41+
...will generate this HTML:
42+
43+
```html
44+
<label class="my-class">
45+
<input type="text" id="my-id" />
46+
</label>
47+
```
48+
49+
## 3.x Behavior
50+
51+
`$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:
52+
53+
```html
54+
<label>
55+
<input type="text" id="my-id" class="my-class" />
56+
</label>
57+
```
58+
59+
## Migration Strategy
60+
61+
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.
62+
63+
## See also
64+
65+
- [Relevant RFC](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0031-attr-fallthrough.md)
66+
- [Migration guide - `$listeners` removed](./listeners-removed.md)
67+
- [Migration guide - New Emits Option](./emits-option.md)
68+
- [Migration guide - `.native` modifier removed](./v-on-native-modifier-removed.md)
69+
- [Migration guide - Changes in the Render Functions API](./render-function-api.md)

src/guide/migration/emits-option.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
---
2+
title: emits Option
3+
badges:
4+
- new
5+
---
6+
7+
# `emits` Option <MigrationBadges :badges="$frontmatter.badges" />
8+
9+
## Overview
10+
11+
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.
12+
13+
## 2.x Behavior
14+
15+
In Vue 2, you can define the props that a component received, but you can't declare which events it can emit:
16+
17+
```html
18+
<template>
19+
<div>
20+
<p>{{ text }}</p>
21+
<button v-on:click="$emit('accepted')">OK</button>
22+
</div>
23+
</template>
24+
<script>
25+
export default {
26+
props: ['text']
27+
}
28+
</script>
29+
```
30+
31+
## 3.x Behavior
32+
33+
Similar to props, the events that the component emits can now be defined with the `emits` option.
34+
35+
```html
36+
<template>
37+
<p>{{ text }}</p>
38+
<button v-on:click="$emit('accepted')">OK</button>
39+
</template>
40+
<script>
41+
export default {
42+
props: ['text'],
43+
emits: ['accepted']
44+
}
45+
</script>
46+
```
47+
48+
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.
49+
50+
For more information on this, please read the [API documentation for this feature](../../api/options-data.md#emits).
51+
52+
## Migration Strategy
53+
54+
It is highly recommended that you document all of the emitted events by your each of components this way because of the [removal of the `.native` modifier](./v-on-native-modifier-removed.md).
55+
56+
All events not defined with `emits` are now added as DOM event listeners to the component's root node (unless `inheritAttrs: false` has been set).
57+
58+
### Example
59+
60+
For components that re-emit native events to their parent, this would now lead to two events being fired:
61+
62+
```vue
63+
<template>
64+
<p>{{ text }}</p>
65+
<button v-on:click="$emit('click', $event)">OK</button>
66+
</template>
67+
<script>
68+
export default {
69+
props: ['text'],
70+
emits: [] // without declared event
71+
}
72+
</script>
73+
```
74+
75+
When a parent listens for the `click` event on the component:
76+
77+
```html
78+
<my-button v-on:click="handleClick"></my-button>
79+
```
80+
81+
it would now be triggered _twice_:
82+
83+
- Once from `$emit()`
84+
- Once from a native event listener applied to the root element
85+
86+
Here you have two options:
87+
88+
1. Properly declare the `click` event. This is useful if you actually do add some logic to that event handler in `<my-button>`
89+
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.
90+
91+
## See also
92+
93+
- [Relevant RFC](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0030-emits-option.md)
94+
- [Migration guide - `.native` modifier removed](./v-on-native-modifier-removed.md)
95+
- [Migration guide - `$listeners` removed](./listeners-removed.md)
96+
- [Migration guide - `$attrs` includes `class` & `style` ](./attrs-includes-class-style.md)
97+
- [Migration guide - Changes in the Render Functions API](./render-function-api.md)

src/guide/migration/introduction.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,22 @@ The following consists a list of breaking changes from 2.x:
6969
- [`key` usage on `<template v-for>` and non-`v-for` nodes has changed](/guide/migration/key-attribute.html)
7070
- [`v-if` and `v-for` precedence when used on the same element has changed](/guide/migration/v-if-v-for.html)
7171
- [`v-bind="object"` is now order-sensitive](/guide/migration/v-bind.html)
72+
- [`v-on:event.native` modifier has been removed](./v-on-native-modifier-removed.md)
7273
- [`ref` inside `v-for` no longer register an array of refs](/guide/migration/array-refs.html)
7374

7475
### Components
7576

7677
- [Functional components can only be created using a plain function](/guide/migration/functional-components.html)
7778
- [`functional` attribute on single-file component (SFC) `<template>` and `functional` component option are deprecated](/guide/migration/functional-components.html)
7879
- [Async components now require `defineAsyncComponent` method to be created](/guide/migration/async-components.html)
80+
- [Component events should now be declared with the `emits` option](./emits-option.md)
7981

8082
### Render Function
8183

8284
- [Render function API changed](/guide/migration/render-function-api.html)
8385
- [`$scopedSlots` property is removed and all slots are exposed via `$slots` as functions](/guide/migration/slots-unification.html)
86+
- [`$listeners` has been removed / merged into `$attrs`](./listeners-removed)
87+
- [`$attrs` now includes `class` and `style` attributes](./attrs-includes-class-style.md)
8488

8589
### Custom Elements
8690

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
---
2+
title: $listeners removed
3+
badges:
4+
- breaking
5+
---
6+
7+
# `$listeners` removed <MigrationBadges :badges="$frontmatter.badges" />
8+
9+
## Overview
10+
11+
The `$listeners` object has been removed in Vue 3. Event listeners are now part of `$attrs`:
12+
13+
```javascript
14+
{
15+
text: 'this is an attribute',
16+
onClose: () => console.log('close Event triggered')
17+
}
18+
```
19+
20+
## 2.x Syntax
21+
22+
In Vue 2, you can access attributes passed to your components with `this.$attrs`, and event listeners with `this.$listeners`.
23+
In combination with `inheritAttrs: false`, they allow the developer to apply these attributes and listeners to some other element instead of the root element:
24+
25+
```html
26+
<template>
27+
<label>
28+
<input type="text" v-bind="$attrs" v-on="$listeners" />
29+
</label>
30+
</template>
31+
<script>
32+
export default {
33+
inheritAttrs: false
34+
}
35+
</script>
36+
```
37+
38+
## 3.x Syntax
39+
40+
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.
41+
42+
```vue
43+
<template>
44+
<label>
45+
<input type="text" v-bind="$attrs" />
46+
</label>
47+
</template>
48+
<script>
49+
export default {
50+
inheritAttrs: false
51+
}
52+
</script>
53+
```
54+
55+
If this component received an `id` attribute and a `v-on:close` listener, the `$attrs` object will now look like this:
56+
57+
```javascript
58+
{
59+
id: 'my-input',
60+
onClose: () => console.log('close Event triggered')
61+
}
62+
```
63+
64+
## Migration Strategy
65+
66+
Remove all usages of `$listeners`.
67+
68+
## See also
69+
70+
- [Relevant RFC](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0031-attr-fallthrough.md)
71+
- [Migration guide - `$attrs`includes `class` & `style` ](./attrs-includes-class-style.md)
72+
- [Migration guide - Changes in the Render Functions API](./render-function-api.md)
73+
- [Migration guide - New Emits Option](./emits-option.md)
74+
- [Migration guide - `.native` modifier removed](./v-on-native-modifier-removed.md)
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
---
2+
title: v-on.native modifier removed
3+
badges:
4+
- breaking
5+
---
6+
7+
# `v-on.native` modifier removed <MigrationBadges :badges="$frontmatter.badges" />
8+
9+
## Overview
10+
11+
The `.native` modifier for `v-on` has been removed.
12+
13+
## 2.x Syntax
14+
15+
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:
16+
17+
```html
18+
<my-component
19+
v-on:close="handleComponentEvent"
20+
v-on:click.native="handleNativeClickEvent"
21+
/>
22+
```
23+
24+
## 3.x Syntax
25+
26+
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.
27+
28+
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).
29+
30+
```html
31+
<my-component
32+
v-on:close="handleComponentEvent"
33+
v-on:click="handleNativeClickEvent"
34+
/>
35+
```
36+
37+
`MyComponent.vue`
38+
39+
```html
40+
<script>
41+
export default {
42+
emits: ['close']
43+
}
44+
</script>
45+
```
46+
47+
## Migration Strategy
48+
49+
- remove all instances of the `.native` modifier.
50+
- ensure that all your components document their events with the `emits` option.
51+
52+
## See also
53+
54+
- [Relevant RFC](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0031-attr-fallthrough.md#v-on-listener-fallthrough)
55+
- [Migration guide - New Emits Option](./emits-option.md)
56+
- [Migration guide - `$listeners` removed](./listeners-removed.md)
57+
- [Migration guide - Changes in the Render Functions API](./render-function-api.md)

0 commit comments

Comments
 (0)