1, the content is personal translation From Vue 3.0 Beta version of the document in chapter 2, not necessarily accurate, welcome to exchange (others have read hundreds of times, say no one to see) 3, the level is limited, at any time eunuch

Global API

Vue 2.x has a number of global apis and configurations that can globally affect how Vue behaves. For example, you can create a global Vue component using the Vue.com Ponent API as follows:

Vue.component('button-counter', {
  data: () = > ({
    count: 0
  }),
  template: '< button@click ="count++"> click {{count}} times. '
})
Copy the code

Similarly, this is how a global directive is defined:

Vue.directive('focus', {
  inserted: el= > el.focus()
})
Copy the code

Admittedly, this approach is convenient, but it also leads to several problems. Technically, Vue 2 does not have an “application” concept. The application we define is simply a root Vue instance created by new Vue(). Each root instance is created by the same Vue constructor, and they share the same global configuration, resulting in:

  • Global configurations can accidentally contaminate other test samples during testing, and users need to be careful to store the source global configurations and restore them to their original state (e.g., reset) after each test sampleVue.config.errorHandler). Some apis likeVue.useVue.mixinThere is no way to reverse the effects of their use. This makes testing involving plug-ins particularly tricky. In fact, vue-test-utils needs to implement a special APIcreateLocalVueTo solve this problem:
import { createLocalVue, mount } from '@vue/test-utils'

// Create a constructor inherited from Vue
const localVue = createLocalVue()

// Mount a plug-in "globally" to the "local" Vue constructor
localVue.use(MyPlugin)

// Pass the Vue constructor to the mount function
mount(Component, { localVue })
Copy the code
  • Such features make it difficult to use different global configurations on different “applications” of the same Vue copy within a page

    // This will affect both root instances
    Vue.mixin({
      / *... * /
    })
    
    const app1 = new Vue({ el: '#app-1' })
    const app2 = new Vue({ el: '#app-2' })
    Copy the code

To avoid these problems, in Vue 3 we introduced:

New global API:createApp

Calling createApp returns an application instance, which is a new concept in Vue 3.

import { createApp } from 'vue'

const app = createApp({})
Copy the code

The application instance exposes a subset of the existing global API. Basically, any API that globally interferes with the behavior of the Vue is now transferred to the application instance. The following table lists the mapping between the existing global and instance apis:

2. X global API 3.x instance API (Application (app))
Vue.config app.config
Vue.config.productionTip Has been 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)

The rest of the apis that do not affect Global behavior are now available for user import as named ES modules, as described in the Global API Treeshaking.

config.productionTipHas been removed

In Vue 3.x, the prompt “Use Production Build” is only displayed when you are building an application using “dev + Full Build” (build mode with runtime + compiler and warnings).

For ES module builds, since they are typically used with packaging tools, and in most cases CLI or template files will configure the production environment, this prompt will no longer be displayed.

config.ignoredElementsNow changed toconfig.isCustomElement

This configuration item was introduced to support native custom elements, so renaming the option this way better expresses what it does. The new option accepts a more flexible function instead of the string/regular expression approach, such as:

/ / before
Vue.config.ignoredElements = ['my-el'./^ion-/]

/ / now,
const app = Vue.createApp({})
app.config.isCustomElement = tag= > tag.startsWith('ion-')
Copy the code

: : : tip is important

In Vue 3.0, the process of checking whether an element is a component moves to template compilation, so this configuration item can only be used in the runtime + compiler version. When building an application using the run-time version, isCustomElement must be passed to @vue/ Compiler-DOM via the build configuration, for example through the compilerOptions option of the VUE – Loader.

  • Used when building applications with run-time only versionsconfig.isCustomElement, the system will pass this parameter through a warning message to prompt the user to build the configuration;
  • This will be a new top-level configuration item for the Vue CLI. : : :

Notes for Plug-in Authors

A common way for authors to import and load plug-ins is to automatically load the UMD version of the plug-in through vue.use. For example, the following shows the official vue-Router plug-in loading in a browser environment:

var inBrowser = typeof window! = ='undefined'
/ *... * /
if (inBrowser && window.Vue) {
  window.Vue.use(VueRouter)
}
Copy the code

In Vue 3, the use global API is no longer used, and the method no longer works and fires a warning when called vue.use (). Instead, the consumer of the plug-in needs to explicitly declare the use of the plug-in in the application instance:

const app = createApp(MyApp)
app.use(VueRouter)
Copy the code

Mount an application instance

When initialized with createApp(/* options */), the application instance app can be mounted to a Vue root instance by app.mount(domTarget) :

import { createApp } from 'vue'
import MyApp from './MyApp.vue'

const app = createApp(MyApp)
app.mount('#app')
Copy the code

With these changes, the component and directive methods mentioned at the beginning of this article could be rewritten like this:

const app = createApp(MyApp)

app.component('button-counter', {
  data: () = > ({
    count: 0
  }),
  template: '< button@click ="count++"> click {{count}} times. '
})

app.directive('focus', {
  mounted: el= > el.focus()
})

// With the component tree, every application instance mounted via app.mount() now gets the same
// "button-counter" component and "focus" command without polluting the global environment.
app.mount('#app')
Copy the code

Provide / Inject

Similar to using the provide parameter on the root instance in 2.x, Vue 3 application instances can provide dependencies that can be injected into any component in the instance:

/ / the entrance
app.provide({
  guide: 'Vue 3 Guide'
})

// at the child component
export default {
  inject: {
    book: {
      from: guide
    }
  },
  template: `<div>{{ book }}</div>`
}
Copy the code

Configuring sharing between applications

Here is one way to share configuration, such as to create a factory function that shares a component or directive:

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')
Copy the code

The focus directive can now be used by Foo and Bar instances and their descendants.