diff --git a/src/.vuepress/config.js b/src/.vuepress/config.js
index 1e1b5e88b0..2c9b4d21a0 100644
--- a/src/.vuepress/config.js
+++ b/src/.vuepress/config.js
@@ -120,9 +120,11 @@ const sidebar = {
'/guide/migration/array-refs',
'/guide/migration/async-components',
'/guide/migration/attribute-coercion',
+ '/guide/migration/attrs-includes-class-style',
'/guide/migration/custom-directives',
'/guide/migration/custom-elements-interop',
'/guide/migration/data-option',
+ '/guide/migration/emits-option',
'/guide/migration/events-api',
'/guide/migration/filters',
'/guide/migration/fragments',
@@ -132,10 +134,12 @@ const sidebar = {
'/guide/migration/inline-template-attribute',
'/guide/migration/key-attribute',
'/guide/migration/keycode-modifiers',
+ '/guide/migration/listeners-removed',
'/guide/migration/props-default-this',
'/guide/migration/render-function-api',
'/guide/migration/slots-unification',
'/guide/migration/transition',
+ '/guide/migration/v-on-native-modifier-removed',
'/guide/migration/v-model',
'/guide/migration/v-if-v-for',
'/guide/migration/v-bind'
diff --git a/src/guide/migration/attrs-includes-class-style.md b/src/guide/migration/attrs-includes-class-style.md
new file mode 100644
index 0000000000..dbb6a5ce52
--- /dev/null
+++ b/src/guide/migration/attrs-includes-class-style.md
@@ -0,0 +1,69 @@
+---
+title: $attrs includes class & style
+badges:
+ - breaking
+---
+
+# `$attrs` includes `class` & `style`
+
+## 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:
+
+```vue
+
+
+
+
+```
+
+when used like this:
+
+```html
+
+```
+
+...will generate this HTML:
+
+```html
+
+```
+
+## 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
+
+```
+
+## 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-function-api.md)
diff --git a/src/guide/migration/emits-option.md b/src/guide/migration/emits-option.md
new file mode 100644
index 0000000000..968a0f41f7
--- /dev/null
+++ b/src/guide/migration/emits-option.md
@@ -0,0 +1,97 @@
+---
+title: emits Option
+badges:
+ - new
+---
+
+# `emits` Option
+
+## 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
+
+
+
{{ text }}
+
+
+
+
+```
+
+## 3.x Behavior
+
+Similar to props, the events that the component emits can now be defined with the `emits` option.
+
+```html
+
+
{{ text }}
+
+
+
+```
+
+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).
+
+## Migration Strategy
+
+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).
+
+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).
+
+### Example
+
+For components that re-emit native events to their parent, this would now lead to two events being fired:
+
+```vue
+
+
{{ text }}
+
+
+
+```
+
+When a parent listens for the `click` event on the component:
+
+```html
+
+```
+
+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 ``
+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.
+
+## 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-function-api.md)
diff --git a/src/guide/migration/introduction.md b/src/guide/migration/introduction.md
index 74cd2eca07..86e73bfed3 100644
--- a/src/guide/migration/introduction.md
+++ b/src/guide/migration/introduction.md
@@ -1,10 +1,10 @@
# Introduction
-::: info
-New to Vue.js? Check out our [Essentials Guide](/guide/introduction.html) to get started.
+::: info
+New to Vue.js? Check out our [Essentials Guide](/guide/introduction.html) to get started.
:::
-This guide is primarily for users with prior Vue 2 experience who want to learn about the new features and changes in Vue 3. **This is not something you have to read from top to bottom before trying out Vue 3.** While it looks like a lot has changed, a lot of what you know and love about Vue is still the same; but we wanted to be as thorough as possible and provide detailed explanations and examples for every documented change.
+This guide is primarily for users with prior Vue 2 experience who want to learn about the new features and changes in Vue 3. **This is not something you have to read from top to bottom before trying out Vue 3.** While it looks like a lot has changed, a lot of what you know and love about Vue is still the same; but we wanted to be as thorough as possible and provide detailed explanations and examples for every documented change.
- [Quickstart](#quickstart)
- [Notable New Features](#notable-new-features)
@@ -69,6 +69,7 @@ The following consists a list of breaking changes from 2.x:
- [`key` usage on `` and non-`v-for` nodes has changed](/guide/migration/key-attribute.html)
- [`v-if` and `v-for` precedence when used on the same element has changed](/guide/migration/v-if-v-for.html)
- [`v-bind="object"` is now order-sensitive](/guide/migration/v-bind.html)
+- [`v-on:event.native` modifier has been removed](./v-on-native-modifier-removed.md)
- [`ref` inside `v-for` no longer register an array of refs](/guide/migration/array-refs.html)
### Components
@@ -76,11 +77,14 @@ The following consists a list of breaking changes from 2.x:
- [Functional components can only be created using a plain function](/guide/migration/functional-components.html)
- [`functional` attribute on single-file component (SFC) `` and `functional` component option are deprecated](/guide/migration/functional-components.html)
- [Async components now require `defineAsyncComponent` method to be created](/guide/migration/async-components.html)
+- [Component events should now be declared with the `emits` option](./emits-option.md)
### Render Function
- [Render function API changed](/guide/migration/render-function-api.html)
- [`$scopedSlots` property is removed and all slots are exposed via `$slots` as functions](/guide/migration/slots-unification.html)
+- [`$listeners` has been removed / merged into `$attrs`](./listeners-removed)
+- [`$attrs` now includes `class` and `style` attributes](./attrs-includes-class-style.md)
### Custom Elements
diff --git a/src/guide/migration/listeners-removed.md b/src/guide/migration/listeners-removed.md
new file mode 100644
index 0000000000..5a84f3592a
--- /dev/null
+++ b/src/guide/migration/listeners-removed.md
@@ -0,0 +1,74 @@
+---
+title: $listeners removed
+badges:
+ - breaking
+---
+
+# `$listeners` removed
+
+## Overview
+
+The `$listeners` object has been removed in Vue 3. Event listeners are now part of `$attrs`:
+
+```javascript
+{
+ text: 'this is an attribute',
+ 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
+
+
+
+
+```
+
+## 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.
+
+```vue
+
+
+
+
+```
+
+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-includes-class-style.md)
+- [Migration guide - Changes in the Render Functions API](./render-function-api.md)
+- [Migration guide - New Emits Option](./emits-option.md)
+- [Migration guide - `.native` modifier removed](./v-on-native-modifier-removed.md)
diff --git a/src/guide/migration/v-on-native-modifier-removed.md b/src/guide/migration/v-on-native-modifier-removed.md
new file mode 100644
index 0000000000..fcaffe0870
--- /dev/null
+++ b/src/guide/migration/v-on-native-modifier-removed.md
@@ -0,0 +1,57 @@
+---
+title: v-on.native modifier removed
+badges:
+ - breaking
+---
+
+# `v-on.native` modifier removed
+
+## 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
+
+```
+
+## 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.
+
+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).
+
+```html
+
+```
+
+`MyComponent.vue`
+
+```html
+
+```
+
+## 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-function-api.md)