Skip to content

Commit 8235a0d

Browse files
committed
docs: final polish for migration guide
1 parent 1dafa6b commit 8235a0d

File tree

9 files changed

+331
-34
lines changed

9 files changed

+331
-34
lines changed

src/.vuepress/config.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ const sidebar = {
111111
collapsable: true,
112112
children: [
113113
'migration/introduction',
114+
'migration/array-refs',
114115
'migration/async-components',
115116
'migration/attribute-coercion',
116117
'migration/custom-directives',
@@ -125,10 +126,13 @@ const sidebar = {
125126
'migration/inline-template-attribute',
126127
'migration/key-attribute',
127128
'migration/keycode-modifiers',
129+
'migration/props-default-this',
128130
'migration/render-function-api',
129131
'migration/slots-unification',
130132
'migration/transition',
131-
'migration/v-model'
133+
'migration/v-model',
134+
'migration/v-if-v-for',
135+
'migration/v-bind'
132136
]
133137
},
134138
{

src/guide/migration/array-refs.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
---
2+
title: v-for Array Refs
3+
badges:
4+
- breaking
5+
---
6+
7+
# {{ $frontmatter.title }} <MigrationBadges :badges="$frontmatter.badges" />
8+
9+
In Vue 2, using the `ref` attribute inside `v-for` will populate the corresponding `$refs` property with an array of refs. This behavior becomes ambiguous and inefficient when there are nested `v-for`s present.
10+
11+
In Vue 3, such usage will no longer automatically create an array in `$refs`. To retrieve multiple refs from a single binding, bind `ref` to a function which provides more flexibility (this is a new feature):
12+
13+
```html
14+
<div v-for="item in list" :ref="setItemRef"></div>
15+
```
16+
17+
With Options API:
18+
19+
```js
20+
export default {
21+
data() {
22+
return {
23+
itemRefs: []
24+
}
25+
},
26+
methods: {
27+
setItemRef(el) {
28+
this.itemRefs.push(el)
29+
}
30+
},
31+
beforeUpdate() {
32+
this.itemRefs = []
33+
},
34+
updated() {
35+
console.log(this.itemRefs)
36+
}
37+
}
38+
```
39+
40+
With Composition API:
41+
42+
```js
43+
import { ref, onBeforeUpdate, onUpdated } from 'vue'
44+
45+
export default {
46+
setup() {
47+
let itemRefs = []
48+
const setItemRef = el => {
49+
itemRefs.push(el)
50+
}
51+
onBeforeUpdate(() => {
52+
itemRefs = []
53+
})
54+
onUpdated(() => {
55+
console.log(itemRefs)
56+
})
57+
return {
58+
itemRefs,
59+
setItemRef
60+
}
61+
}
62+
}
63+
```
64+
65+
Note that:
66+
67+
- `itemRefs` doesn't have to be an array: it can also be an object where the refs are set by their iteration keys.
68+
69+
- This also allows `itemRefs` to be made reactive and watched, if needed.

src/guide/migration/custom-elements-interop.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ badges:
33
- breaking
44
---
55

6-
# Custom Elements Interop changes <MigrationBadges :badges="$frontmatter.badges" />
6+
# Custom Elements Interop <MigrationBadges :badges="$frontmatter.badges" />
77

88
# Overview
99

src/guide/migration/data-option.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ badges:
1010

1111
- **BREAKING**: `data` component option declaration no longer accepts a plain JavaScript `object` and expects a `function` declaration.
1212

13+
- **BREAKING**: when merging multiple `data` return values from mixins or extends, the merge is now shallow instead of deep (only root-level properties are merged).
14+
1315
## 2.x Syntax
1416

1517
In 2.x, developers could define the `data` option with either an `object` or a `function`.
@@ -60,9 +62,60 @@ Using the example above, there would only be one possible implementation of the
6062
</script>
6163
```
6264

65+
## Mixin Merge Behavior Change
66+
67+
In addition, when `data()` from a component and its mixins or extends base are merged, the merge is now performed *shallowly*:
68+
69+
```js
70+
const Mixin = {
71+
data() {
72+
return {
73+
user: {
74+
name: 'Jack',
75+
id: 1
76+
}
77+
}
78+
}
79+
}
80+
81+
const CompA = {
82+
mixins: [Mixin],
83+
data() {
84+
return {
85+
user: {
86+
id: 2
87+
}
88+
}
89+
}
90+
}
91+
```
92+
93+
In Vue 2.x, the resulting `$data` is:
94+
95+
```json
96+
{
97+
user: {
98+
id: 2,
99+
name: 'Jack'
100+
}
101+
}
102+
```
103+
104+
In 3.0, the result will be:
105+
106+
```json
107+
{
108+
user: {
109+
id: 2
110+
}
111+
}
112+
```
113+
63114
## Migration Strategy
64115

65116
For users relying on the object declaration, we recommend:
66117

67118
- Extracting the shared data into an external object and using it as a property in `data`
68119
- Rewrite references to the shared data to point to a new shared object
120+
121+
For users relying on the deep merge behavior from mixins, we recommend refactoring your code to avoid such reliance altogether, since deep merges from mixins are very implicit and can make the code logic more difficult to understand and debug.

src/guide/migration/introduction.md

Lines changed: 132 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
# Introduction
22

3-
> There's so much here! Does that mean 3.0 is completely different, I'll have to learn the basics all over again, and migrating will be practically impossible?
3+
This guide is primarily for users with prior Vue 2 experience who want to learn about the new features and changes in Vue 3. The lists may look long, but it is because we want to be as thorough as possible and provide detailed examples for every documented change. **This is not something you have to read from top to bottom before trying out Vue 3.**
44

5-
We're glad you asked! The answer is no. We've gone to great lengths to ensure most of the API is the same and the core concepts haven't changed. It's long because we like to offer very detailed explanations and include a lot of examples. Rest assured, **this is not something you have to read from top to bottom!**
6-
7-
Possibly the biggest change is our new [Composition API](/guide/composition-api-introduction.html), which is entirely additive- the previous Options API will continue to be supported, as the Composition API is an advanced feature.
5+
- [Quickstart](#quickstart)
6+
- [New Features](#new-features)
7+
- [Breaking Changes](#breaking-changes)
8+
- [Supporting Libraries](#supporting-libraries)
89

910
## Overview
1011

@@ -13,67 +14,167 @@ Possibly the biggest change is our new [Composition API](/guide/composition-api-
1314

1415
Start learning Vue 3 at [Vue Mastery](https://www.vuemastery.com/courses-path/vue3).
1516

16-
### New Features
17+
## Quickstart
18+
19+
- Via CDN: `<script src="https://unpkg.com/vue@next"></script>`
20+
- In-browser playground on [Codepen](https://codepen.io/yyx990803/pen/OJNoaZL)
21+
- Scaffold via [Vite](https://github.com/vitejs/vite):
22+
23+
```bash
24+
npm init vite-app hello-vue3 # OR yarn create vite-app hello-vue3
25+
```
26+
27+
- Scaffold via [vue-cli](https://cli.vuejs.org/):
28+
29+
```bash
30+
npm install -g @vue/cli # OR yarn global add @vue/cli
31+
vue create hello-vue3
32+
# select vue 3 preset
33+
```
34+
35+
## New Features
1736

1837
Some of the new features to keep an eye on in Vue 3 include:
1938

2039
- [Composition API](/guide/composition-api-introduction.html)
2140
- [Teleport](/guide/teleport.html)
2241
- [Fragments](/guide/migration/fragments.html)
2342
- [Emits Component Option](/guide/component-custom-events.html)
24-
- `createRenderer` API from `@vue/runtime-core` to create custom renderers
43+
- [`createRenderer` API from `@vue/runtime-core`](https://github.com/vuejs/vue-next/tree/master/packages/runtime-core) to create custom renderers
44+
- [SFC Composition API Syntax Sugar (`<script setup>`)](https://github.com/vuejs/rfcs/blob/sfc-improvements/active-rfcs/0000-sfc-script-setup.md) <Badge text="experimental" type="warning" />
45+
- [SFC State-driven CSS Variables (`<style vars>`)](https://github.com/vuejs/rfcs/blob/sfc-improvements/active-rfcs/0000-sfc-style-variables.md) <Badge text="experimental" type="warning" />
46+
47+
## Breaking Changes
2548

26-
### Breaking
49+
::: tip
50+
We are still working on a dedicated Migration Build of Vue 3 with Vue 2 compatible behavior and runtime warnings of incompatible usage. If you are planning to migrate a non-trivial Vue 2 app, we strongly recommend waiting for the Migration Build for a smoother experience.
51+
:::
2752

2853
The following consists a list of breaking changes from 2.x:
2954

55+
### Global API
56+
3057
- [Global Vue API is changed to use an application instance](/guide/migration/global-api.html)
3158
- [Global and internal APIs have been restructured to be tree-shakable](/guide/migration/global-api-treeshaking.html)
32-
- [`model` component option and `v-bind`'s `sync` modifier are removed in favor of `v-model` arguments](/guide/migration/v-model.html)
33-
- [Render function API changed](/guide/migration/render-function-api.html)
59+
60+
### Template Directives
61+
62+
- [`v-model` usage on components has been reworked](/guide/migration/v-model.html)
63+
- [`key` usage on `<template v-for>` and non-`v-for` nodes has changed](/guide/migration/key-attribute.html)
64+
- [`v-if` and `v-for` precedence when used on the same element has changed](/guide/migration/v-if-v-for.html)
65+
- [`v-bind="object"` is now order-sensitive](/guide/migration/v-bind.html)
66+
- [`ref` inside `v-for` no longer register an array of refs](/guide/migration/array-refs.html)
67+
68+
### Components
69+
3470
- [Functional components can only be created using a plain function](/guide/migration/functional-components.html)
3571
- [`functional` attribute on single-file component (SFC) `<template>` and `functional` component option are deprecated](/guide/migration/functional-components.html)
3672
- [Async components now require `defineAsyncComponent` method to be created](/guide/migration/async-components.html)
37-
- [Component data option should always be declared as a function](/guide/migration/data-option.html)
38-
- [Custom elements whitelisting is now performed during template compilation](/guide/migration/custom-elements-interop.html)
39-
- [Special `is` prop usage is restricted to the reserved `<component>` tag only](/guide/migration/custom-elements-interop.html)
73+
74+
### Render Function
75+
76+
- [Render function API changed](/guide/migration/render-function-api.html)
4077
- [`$scopedSlots` property is removed and need to be replaced with `$slots`](/guide/migration/slots-unification.html)
41-
- [Attributes coercion strategy changed](/guide/migration/attribute-coercion.html)
78+
79+
### Custom Elements
80+
81+
- [Custom elements whitelisting is now performed during template compilation](/guide/migration/custom-elements-interop.html)
82+
- [Special `is` prop usage is restricted to the reserved `<component>` tag only](/guide/migration/custom-elements-interop.html#customized-built-in-elements)
83+
84+
### Other Minor Changes
85+
86+
- The ~~`destroyed`~~ lifecycle option has been renamed to `unmounted`
87+
- The ~~`beforeDestroy`~~ lifecycle option has been renamed to `beforeUnmount`
88+
- [Props `default` factory function no longer has access to `this` context](/guide/migration/props-default-this.html)
4289
- [Custom directive API changed to align with component lifecycle](/guide/migration/custom-directives.html)
43-
- [Some transition classes got a rename](/guide/migration/transition.md)
44-
- [Component watch option](/api/options-data.html#watch) and [instance method `$watch`](/api/instance-methods.html#watch) no longer supports dot-delimited string paths, use a computed function as the parameter instead
45-
- [Changes in `key` attribute usage with `v-if` and `<template v-for>`](/guide/migration/key-attribute.md)
46-
- In Vue 2.x, application root container's `outerHTML` is replaced with root component template (or eventually compiled to a template, if root component has no template/render option). Vue 3.x now uses application container's `innerHTML` instead.
90+
- [The `data` option should always be declared as a function](/guide/migration/data-option.html)
91+
- [The `data` option from mixins is now merged shallowly](/guide/migration/data-option.html#mixin-merge-behavior-change)
92+
- [Attributes coercion strategy changed](/guide/migration/attribute-coercion.html)
93+
- [Some transition classes got a rename](/guide/migration/transition.html)
94+
- [Component watch option](/api/options-data.html#watch) and [instance method `$watch`](/api/instance-methods.html#watch) no longer supports dot-delimited string paths, use a computed function as the parameter instead.
95+
- `<template>` tags with no special directives (`v-if/else-if/else`, `v-for`, or `v-slot`) are now treated as plain elements and will result in a native `<template>` element instead of rendering its inner content.
96+
- In Vue 2.x, application root container's `outerHTML` is replaced with root component template (or eventually compiled to a template, if root component has no template/render option). Vue 3.x now uses application container's `innerHTML` instead - this means the container itself is no longer considered part of the template.
4797

48-
### Removed
98+
### Removed APIs
4999

50100
- [`keyCode` support as `v-on` modifiers](/guide/migration/keycode-modifiers.html)
51101
- [$on, $off and \$once instance methods](/guide/migration/events-api.html)
52102
- [Filters](/guide/migration/filters.html)
53103
- [Inline templates attributes](/guide/migration/inline-template-attribute.html)
104+
- `$destroy` instance method. Users should no longer manually manage the lifecycle of individual Vue components.
105+
106+
## Supporting Libraries
107+
108+
All of our official libraries and tools now support Vue 3, but most of them are still in beta status and distributed under the `next` dist tag on NPM. **We are planning to stabilize and switch all projects to use the `latest` dist tag by end of 2020.**
109+
110+
### Vue CLI
111+
112+
As of v4.5.0, `vue-cli` now provides built-in option to choose Vue 3 preset when creating a new project. You can upgrade `vue-cli` and run `vue create` to create a Vue 3 project today.
113+
114+
### Vue Router
115+
116+
Vue Router 4.0 provides Vue 3 support and has a number of breaking changes of its own. Check out its [README](https://github.com/vuejs/vue-router-next#vue-router-next-) for full details.
117+
118+
- [![beta](https://img.shields.io/npm/v/vue-router/next.svg)](https://www.npmjs.com/package/vue-router/v/next)
119+
- [Github](https://github.com/vuejs/vue-router-next)
120+
- [RFCs](https://github.com/vuejs/rfcs/pulls?q=is%3Apr+is%3Amerged+label%3Arouter)
121+
122+
### Vuex
123+
124+
Vuex 4.0 provides Vue 3 support with largely the same API as 3.x. The only breaking change is [how the plugin is installed](https://github.com/vuejs/vuex/tree/4.0#breaking-changes).
125+
126+
- [![beta](https://img.shields.io/npm/v/vuex/next.svg)](https://www.npmjs.com/package/vuex/v/next)
127+
- [Github](https://github.com/vuejs/vuex/tree/4.0)
128+
129+
### Devtools Extension
130+
131+
We are working on a new version of the Devtools with a new UI and refactored internals to support multiple Vue versions. The new version is currently in beta and only supports Vue 3 (for now). Vuex and Router integration is also work in progress.
54132

55-
## FAQ
133+
- For Chrome: [Install from Chrome web store](https://chrome.google.com/webstore/detail/vuejs-devtools/ljjemllljcmogpfapbkkighbhhppjdbg?hl=en)
56134

57-
### Where should I start in a migration?
135+
- Note: the beta channel may conflict with the stable version of devtools so you may need to temporarily disable the stable version for the beta channel to work properly.
58136

59-
1. Start by running the migration helper (still under development) on a current project. We've carefully minified and compressed a senior Vue dev into a simple command line interface. Whenever they recognize an obsolete feature, they'll let you know, offer suggestions, and provide links to more info.
137+
- For Firefox: [Download the signed extension](https://github.com/vuejs/vue-devtools/releases/tag/v6.0.0-beta.2) (`.xpi` file under Assets)
60138

61-
2. After that, browse through the table of contents for this page in the sidebar. If you see a topic you may be affected by, but the migration helper didn't catch, check it out.
139+
### Other Projects
62140

63-
3. If you have any tests, run them and see what still fails. If you don't have tests, just open the app in your browser and keep an eye out for warnings or errors as you navigate around.
141+
| Project | NPM | Repo |
142+
| ------------------- | --- | ---- |
143+
| @vue/babel-plugin-jsx | [![rc][jsx-badge]][jsx-npm] | [[Github][jsx-code]] |
144+
| eslint-plugin-vue | [![beta][epv-badge]][epv-npm] | [[Github][epv-code]] |
145+
| @vue/test-utils | [![beta][vtu-badge]][vtu-npm] | [[Github][vtu-code]] |
146+
| vue-class-component | [![beta][vcc-badge]][vcc-npm] | [[Github][vcc-code]] |
147+
| vue-loader | [![beta][vl-badge]][vl-npm] | [[Github][vl-code]] |
148+
| rollup-plugin-vue | [![beta][rpv-badge]][rpv-npm] | [[Github][rpv-code]] |
64149

65-
4. By now, your app should be fully migrated. If you're still hungry for more though, you can read the rest of this page - or dive in to the new and improved guide from [the beginning](#overview). Many parts will be skimmable, since you're already familiar with the core concepts.
150+
[jsx-badge]: https://img.shields.io/npm/v/@vue/babel-plugin-jsx.svg
151+
[jsx-npm]: https://www.npmjs.com/package/@vue/babel-plugin-jsx
152+
[jsx-code]: https://github.com/vuejs/jsx-next
66153

67-
### How long will it take to migrate a Vue 2.x app to 3.0?
154+
[vd-badge]: https://img.shields.io/npm/v/@vue/devtools/beta.svg
155+
[vd-npm]: https://www.npmjs.com/package/@vue/devtools/v/beta
156+
[vd-code]: https://github.com/vuejs/vue-devtools/tree/next
68157

69-
It depends on a few factors:
158+
[epv-badge]: https://img.shields.io/npm/v/eslint-plugin-vue/next.svg
159+
[epv-npm]: https://www.npmjs.com/package/eslint-plugin-vue/v/next
160+
[epv-code]: https://github.com/vuejs/eslint-plugin-vue
70161

71-
- The size of your app (small to medium-sized apps will probably be less than a day)
162+
[vtu-badge]: https://img.shields.io/npm/v/@vue/test-utils/next.svg
163+
[vtu-npm]: https://www.npmjs.com/package/@vue/test-utils/v/next
164+
[vtu-code]: https://github.com/vuejs/vue-test-utils-next
72165

73-
- How many times you get distracted and start playing with a cool new feature. 😉 &nbsp;Not judging, it also happened to us while building 3.0!
166+
[jsx-badge]: https://img.shields.io/npm/v/@ant-design-vue/babel-plugin-jsx.svg
167+
[jsx-npm]: https://www.npmjs.com/package/@ant-design-vue/babel-plugin-jsx
168+
[jsx-code]: https://github.com/vueComponent/jsx
74169

75-
- Which obsolete features you're using. Most can be upgraded with find-and-replace, but others might take a few minutes. If you're not currently following best practices according to [our styleguide](/style-guide/), Vue 3.0 will also try harder to force you to. This is a good thing in the long run, but could also mean a significant (though possibly overdue) refactor.
170+
[vcc-badge]: https://img.shields.io/npm/v/vue-class-component/next.svg
171+
[vcc-npm]: https://www.npmjs.com/package/vue-class-component/v/next
172+
[vcc-code]: https://github.com/vuejs/vue-class-component/tree/next
76173

77-
### If I upgrade to Vue 3, will I also have to upgrade Vuex and Vue Router?
174+
[vl-badge]: https://img.shields.io/npm/v/vue-loader/next.svg
175+
[vl-npm]: https://www.npmjs.com/package/vue-loader/v/next
176+
[vl-code]: https://github.com/vuejs/vue-loader/tree/next
78177

79-
Yes, currently both [Vuex](https://github.com/vuejs/vuex/tree/4.0#vuex-4) and [Vue Router](https://github.com/vuejs/vue-router-next) are in beta
178+
[rpv-badge]: https://img.shields.io/npm/v/rollup-plugin-vue/next.svg
179+
[rpv-npm]: https://www.npmjs.com/package/rollup-plugin-vue/v/next
180+
[rpv-code]: https://github.com/vuejs/rollup-plugin-vue/tree/next

src/guide/migration/key-attribute.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ badges:
88
## Overview
99

1010
- **NEW:** `key`s are no longer necessary on `v-if`/`v-else`/`v-else-if` branches, since Vue now automatically generates unique `key`s.
11-
- **BREAKING:** If you manually provide `key`s, then each branch must use a unique `key`.
11+
- **BREAKING:** If you manually provide `key`s, then each branch must use a unique `key`. You can no longer intentionally use the same `key` to force branch reuse.
1212
- **BREAKING:** `<template v-for>` `key` should be placed on the `<template>` tag (rather than on its children).
1313

1414
## Background

0 commit comments

Comments
 (0)