Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit f3ad69a

Browse filesBrowse files
authored
Add Global API Changes migration page (#125)
1 parent 69ce338 commit f3ad69a
Copy full SHA for f3ad69a

File tree

Expand file treeCollapse file tree

4 files changed

+216
-8
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+216
-8
lines changed

‎src/.vuepress/config.js

Copy file name to clipboardExpand all lines: src/.vuepress/config.js
+9-7Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,10 @@ const sidebar = {
5555
{
5656
title: 'Tooling',
5757
collapsable: false,
58-
children: ['/guide/single-file-component']
58+
children: [
59+
'/guide/single-file-component',
60+
'/guide/testing'
61+
]
5962
},
6063
{
6164
title: 'Scaling Up',
@@ -67,15 +70,14 @@ const sidebar = {
6770
'/guide/accessibility'
6871
]
6972
},
70-
{
71-
title: 'Tooling',
72-
collapsable: false,
73-
children: ['/guide/testing']
74-
},
7573
{
7674
title: 'Migration to Vue 3',
7775
collapsable: true,
78-
children: ['migration', 'migration/functional-components']
76+
children: [
77+
'migration/global-api',
78+
'migration/treeshaking',
79+
'migration/functional-components'
80+
]
7981
},
8082
{
8183
title: 'Contribute to the Docs',

‎src/.vuepress/styles/index.styl

Copy file name to clipboardExpand all lines: src/.vuepress/styles/index.styl
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
position: relative;
1818
border-bottom-right-radius: 2px;
1919
border-top-right-radius: 2px;
20-
max-width: 80%;
2120
margin: 1rem 0;
2221

2322
&::before {

‎src/guide/migration/global-api.md

Copy file name to clipboard
+204Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
# Global API Changes
2+
3+
Vue 2.x has a number of global APIs and configurations that globally mutate Vue’s behavior. For instance, to create a global component, you would use the `Vue.component` API like this:
4+
5+
``` js
6+
Vue.component('button-counter', {
7+
data: () => ({
8+
count: 0
9+
}),
10+
template: '<button @click="count++">Clicked {{ count }} times.</button>'
11+
})
12+
```
13+
14+
Similarly, this is how a global directive is declared:
15+
16+
``` js
17+
Vue.directive('focus', {
18+
inserted: el => el.focus()
19+
})
20+
```
21+
22+
While this approach is convenient, it leads to a couple of problems. Technically, Vue 2 doesn't have a concept of an "app". What we define as an app is simply a root Vue instance created via `new Vue()`. Every root instance created from the same Vue constructor **shares the same global configuration**. As a result:
23+
24+
* Global configuration makes it easy to accidentally pollute other test cases during testing. Users need to carefully store original global configuration and restore it after each test (e.g. resetting `Vue.config.errorHandler`). Some APIs like `Vue.use` and `Vue.mixin` don't even have a way to revert their effects. This makes tests involving plugins particularly tricky. In fact, vue-test-utils has to implement a special API `createLocalVue` to deal with this:
25+
26+
``` js
27+
import { createLocalVue, mount } from '@vue/test-utils'
28+
29+
// create an extended `Vue` constructor
30+
const localVue = createLocalVue()
31+
32+
// install a plugin “globally” on the “local” Vue constructor
33+
localVue.use(MyPlugin)
34+
35+
// pass the `localVue` to the mount options
36+
mount(Component, { localVue })
37+
```
38+
39+
* Global configuration makes it difficult to share the same copy of Vue between multiple "apps" on the same page, but with different global configurations.
40+
41+
```js
42+
// this affects both root instances
43+
Vue.mixin({ /* ... */ })
44+
45+
const app1 = new Vue({ el: '#app-1' })
46+
const app2 = new Vue({ el: '#app-2' })
47+
```
48+
49+
To avoid these problems, in Vue 3 we introduce…
50+
51+
## A New Global API: `createApp`
52+
53+
Calling `createApp` returns an _app instance_, a new concept in Vue 3.
54+
55+
```js
56+
import { createApp } from 'vue'
57+
58+
const app = createApp()
59+
```
60+
61+
An app instance exposes a subset of the current global APIs. The rule of thumb is _any APIs that globally mutate Vue's behavior are now moved to the app instance_. Here is a table of the current global APIs and their corresponding instance APIs:
62+
63+
| 2.x Global API | 3.x Instance API (`app`) |
64+
|----------------|--------------------------|
65+
| Vue.config | app.config |
66+
| Vue.config.productionTip | _removed_ ([see below](config-productiontip-removed)) |
67+
| Vue.config.ignoredElements | app.config.isCustomElement ([see below](#config-ignoredelements-is-now-config-iscustomelement)) |
68+
| Vue.component | app.component |
69+
| Vue.directive | app.directive |
70+
| Vue.mixin | app.mixin |
71+
| Vue.use | app.use ([see below](#a-note-for-plugin-authors)) |
72+
73+
All other global APIs that do not globally mutate behavior are now named exports, as documented in [Global API Treeshaking](./treeshaking.html).
74+
75+
### `config.productionTip` Removed
76+
77+
In Vue 3.x, the "use production build" tip will only show up when using the "dev + full build" (the build that includes the runtime compiler and has warnings).
78+
79+
For ES modules builds, since they are used with bundlers, and in most cases a CLI or boilerplate would have configured the production env properly, this tip will no longer show up.
80+
81+
### `config.ignoredElements` Is Now `config.isCustomElement`
82+
83+
This config option was introduced with the intention to support native custom elements, so the renaming better conveys what it does. The new option also expects a function which provides more flexibility than the old string / RegExp approach:
84+
85+
``` js
86+
// before
87+
Vue.config.ignoredElements = ['my-el', /^ion-/]
88+
89+
// after
90+
const app = Vue.createApp()
91+
app.config.isCustomElement = tag => tag.startsWith('ion-')
92+
```
93+
94+
::: tip Important
95+
96+
In 3.0, the check of whether an element is a component or not has been moved to the template compilation phase, therefore this config option is only respected when using the runtime compiler. If you are using the runtime-only build, `isCustomElement` must be passed to `@vue/compiler-dom` in the build setup instead - for example, via the [`compilerOptions` option in vue-loader](https://vue-loader.vuejs.org/options.html#compileroptions).
97+
98+
* If `config.isCustomElement` is assigned to when using a runtime-only build, a warning will be emitted instructing the user to pass the option in the build setup instead;
99+
* This will be a new top-level option in the Vue CLI config.
100+
:::
101+
102+
### A Note for Plugin Authors
103+
104+
It is a common practice for plugin authors to install the plugins automatically in their UMD builds using `Vue.use`. For instance, this is how the official `vue-router` plugin installs itself in a browser environment:
105+
106+
```js
107+
var inBrowser = typeof window !== 'undefined';
108+
/**/
109+
if (inBrowser && window.Vue) {
110+
window.Vue.use(VueRouter);
111+
}
112+
```
113+
114+
As the `use` global API is no longer available in Vue 3, this method will cease to work and calling `Vue.use()` will now trigger a warning. Instead, the end-user will now have to explicitly specify using the plugin on the app instance:
115+
116+
```js
117+
const app = createApp(MyApp)
118+
app.use(VueRouter)
119+
```
120+
121+
## Mounting App Instance
122+
123+
After being initialized with `createApp()`, the app instance `app` can be used to mount a Vue root instance with `app.mount(VueInstance, domTarget)`:
124+
125+
```js
126+
import { createApp } from 'vue'
127+
import MyApp from './MyApp.vue'
128+
129+
const app = createApp()
130+
app.mount(MyApp, ‘#app’)
131+
```
132+
133+
The `mount` method can also accept props to be passed to the root component via a third argument:
134+
135+
```js
136+
app.mount(MyApp, '#app', {
137+
// props to be passed to root component
138+
})
139+
```
140+
141+
With all these changes, the component and directive we have at the beginning of the guide will be rewritten into something like this:
142+
143+
``` js
144+
const app = createApp()
145+
146+
app.component('button-counter', {
147+
data: () => ({
148+
count: 0
149+
}),
150+
template: '<button @click="count++">Clicked {{ count }} times.</button>'
151+
})
152+
153+
app.directive('focus', {
154+
inserted: el => el.focus()
155+
})
156+
157+
// now every Vue instance mounted with app.mount(), along with its
158+
// component tree, will have the same “button-counter” component
159+
// and “focus” directive without polluting the global environment
160+
app.mount(MyApp, '#app')
161+
```
162+
163+
## Provide / Inject
164+
165+
Similar to using the `provide` option in a 2.x root instance, a Vue 3 app instance can also provide dependencies that can be injected by any component inside the app:
166+
167+
```js
168+
// in the entry
169+
app.provide({
170+
[ThemeSymbol]: theme
171+
})
172+
173+
// in a child component
174+
export default {
175+
inject: {
176+
theme: {
177+
from: ThemeSymbol
178+
}
179+
},
180+
template: `<div :style="{ color: theme.textColor }" />`
181+
}
182+
```
183+
184+
## Share Configurations Among Apps
185+
186+
One way to share configurations e.g. components or directives among apps is to create a factory function, like this:
187+
188+
```js
189+
import { createApp } from 'vue'
190+
import Foo from './Foo.vue'
191+
import Bar from './Bar.vue'
192+
193+
const createMyApp = () => {
194+
const app = createApp()
195+
app.directive('focus', /* ... */)
196+
197+
return app
198+
}
199+
200+
createApp().mount(Foo, '#foo')
201+
createApp().mount(Bar, '#bar')
202+
```
203+
204+
Now the `focus` directive will be available in both Foo and Bar instances and their descendants.

‎src/guide/migration/treeshaking.md

Copy file name to clipboard
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Global API Treeshaking
2+
3+
<!--Tmp. placeholder for linking purpose-->

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.