Menu
Why
In vue2, there were two problems:
- Global configuration makes it easy to accidentally pollute other test cases during testing. The reason is that global apis such as
Vue.useandVue.mixincan cause some effects which are shared among every root instance. - Global configuration makes it difficult to share the same copy of a Vue instance between multiple “apps” on the same page, but with different global configurations.
New Global API: createApp
Different from vue2, vue3 has a new concept called app instance instead root instance before.
In vue3, we can call createApp to create an app instance.
import { createApp } from 'vue'const app = createApp({})
If you use a CDN build of Vue3, you can get createApp api from global Vue object.
const { createApp } from Vueconst app = createApp({})
An app instance contains any APIs that globally mutate Vue’s behavior in vue3. Because of this, global configurations are isolated among app instances.
Here is a table of the Vue2 global APIs and their corresponding instance APIs in vue3:
| 2.x Global API | 3.x Instance API (app) |
|---|---|
| Vue.config | app.config |
| Vue.config.productionTip | removed (see below) |
| Vue.config.ignoredElements | app.config.isCustomElement (see below) |
| Vue.component | app.component |
| Vue.directive | app.directive |
| Vue.mixin | app.mixin |
| Vue.use | app.use (see below) |
| Vue.prototype | app.config.globalProperties (see below) |
All other global APIs that do not globally mutate behavior are now named exports, as documented in Global API Treeshaking.
config.productionTip Removed
In vue3, the “use production build” tip will only show up when using the “dev + full build” (the build includes the runtime compiler and has warning).
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.
config.ignoredElements is Now config.isCustomElement
This config option is for supporting native custom elements, so the renaming better conveys what it does. The new option provide a function usage to replace the old string / RegExp approach for for more flexibility:
// vue2.xVue.config.ignoredElements = ['costomtable', /^custom-/]// vue3.xconst app = createApp({})app.config.isCustomElement = tag => tag.startsWith('custom-')
Important
n Vue 3, 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,
isCustomElementmust be passed to@vue/compiler-domin the build setup instead - for example, via thecompilerOptionsoption in vue-loader (opens new window).
- If
config.isCustomElementis 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;- This will be a new top-level option in the Vue CLI config.
Vue.prototype Replaced by config.globalProperties
Vue.prototype was designed to add properties that would be accessible in all child components.
The original intention was good. But in muti-root projects, global configurations can pollute all root instances. This is why creating config.globalProperties. Every properties in it will be only accessible in components within app instances.
A Note for Plugin Authors
In vue2, vue installs a plugin like this in a browser environment:
var inBrowser = typeof window !== 'undefined'/* ... */if (inBrowser && window.Vue) {window.Vue.use(VueRouter)}
Now Vue.use has been removed. You can use plugins like this:
const app = createApp(MyApp)app.use(VueRouter)
Mounting App Instance
Mouting app instance:
import { createApp } from 'vue'import MyApp from './MyApp.vue'const app = createApp(MyApp)app.mount('#app')
How to initilize a global component or a directive:
const app = createApp(MyApp)app.component('button-counter', {data: () => ({count: 0}),template: '<button @click="count++">Clicked {{ count }} times.</button>'})app.directive('focus', {mounted: el => el.focus()})// now every application instance mounted with app.mount(), along with its// component tree, will have the same “button-counter” component// and “focus” directive without polluting the global environmentapp.mount('#app')
Provide / Inject
// in the entryapp.provide('guide', 'Vue 3 Guide')// in a child componentexport default {inject: {book: {from: 'guide'}},template: `<div>{{ book }}</div>`}
Share Configurations Among Apps
import { createApp } from 'vue'import Foo from './Foo.vue'import Bar from './Bar.vue'const createMyApp = options => {const app = createApp(options)app.directive('focus', /* ... */)return app}createMyApp(Foo).mount('#foo')createMyApp(Bar).mount('#bar')

