app.config errorHandler signature
The errorHandler on AppConfig has signature: errorHandler?: (err: unknown, instance: ComponentPublicInstance | null, info: string) => void. The error handler receives three arguments: the error, the component instance that triggered the error, and an information string specifying the error source type. It can capture errors from component renders, event handlers, lifecycle hooks, setup() function, watchers, custom directive hooks, and transition hooks. In production, the info argument is a shortened code instead of the full string; codes can be looked up in the Production Error Code Reference.
app.config warnHandler signature
The warnHandler on AppConfig has signature: warnHandler?: (msg: string, instance: ComponentPublicInstance | null, trace: string) => void. The warning handler receives the warning message as the first argument, the source component instance as the second argument, and a component trace string as the third. It can filter out specific warnings to reduce console verbosity. Warnings only work during development; this config is ignored in production mode.
app.config.performance for performance tracing
The performance property on AppConfig has type boolean. Set to true to enable component init, compile, render and patch performance tracing in the browser devtool performance/timeline panel. Only works in development mode and in browsers that support the performance.mark API.
app.config.compilerOptions overview
The compilerOptions on AppConfig allows configuring runtime compiler options. Values set on this object are passed to the in-browser template compiler and affect every component in the configured app. These options can also be overridden on a per-component basis using the compilerOptions option. This config option is only respected when using the full build (standalone vue.js that compiles templates in the browser); with the runtime-only build, compiler options must be passed via build tool configurations instead (vue-loader's compilerOptions loader option or @vitejs/plugin-vue options).
app.config.compilerOptions.isCustomElement
The isCustomElement on compilerOptions has type: (tag: string) => boolean. It specifies a check method to recognize native custom elements. Should return true if the tag should be treated as a native custom element; Vue will render it as a native element instead of attempting to resolve it as a Vue component. Native HTML and SVG tags do not need to be matched in this function; Vue's parser recognizes them automatically.
app.config.compilerOptions.whitespace
The whitespace on compilerOptions has type: 'condense' | 'preserve'. Default: 'condense'. It adjusts template whitespace handling behavior. In 'condense' mode: (1) leading/ending whitespace inside an element is condensed to a single space, (2) whitespace between elements containing newlines is removed, (3) consecutive whitespace in text nodes is condensed to a single space. Setting to 'preserve' disables behaviors (2) and (3).
app.config.compilerOptions.delimiters
The delimiters on compilerOptions has type: [string, string]. Default: ['{{', '}}']. It adjusts the delimiters used for text interpolation within the template. This is typically used to avoid conflicting with server-side frameworks that also use mustache syntax.
app.config.compilerOptions.comments
The comments on compilerOptions has type: boolean. Default: false. It adjusts treatment of HTML comments in templates. By default, Vue removes comments in production. Setting to true forces Vue to preserve comments even in production. Comments are always preserved during development. This option is typically used when Vue is used with libraries that rely on HTML comments.
app.config.globalProperties for global properties
The globalProperties on AppConfig has type: Record<string, any>. It is an object that can be used to register global properties accessible on any component instance inside the application. This is a replacement for Vue 2's Vue.prototype. It should be used sparingly. If a global property conflicts with a component's own property, the component's own property has higher priority.
app.config.globalProperties usage example
Example showing global properties configuration:
```js
app.config.globalProperties.msg = 'hello'
```
This makes `msg` available inside any component template in the application, and also on `this` of any component instance:
```js
export default {
mounted() {
console.log(this.msg) // 'hello'
}
}
```
app.config.optionMergeStrategies for custom option merging
The optionMergeStrategies on AppConfig has type: Record<string, OptionMergeFunction> where OptionMergeFunction = (to: unknown, from: unknown) => any. It defines merging strategies for custom component options. A merge strategy function receives the value of that option defined on the parent and child instances as the first and second arguments respectively. This is used when plugins/libraries add support for custom component options that need special merging logic.
app.config.idPrefix for generated IDs
The idPrefix on AppConfig has type: string. Default: undefined. Available in Vue 3.5+. It configures a prefix for all IDs generated via useId() inside the application.
app.config.throwUnhandledErrorInProduction
The throwUnhandledErrorInProduction on AppConfig has type: boolean. Default: false. Available in Vue 3.5+. It forces unhandled errors to be thrown in production mode. By default, errors have different behavior between development (thrown and crash-prone) and production (logged to console). Setting to true makes errors throw even in production, allowing error monitoring services to catch them.
app.config.errorHandler example
Example showing error handler configuration:
```js
app.config.errorHandler = (err, instance, info) => {
// handle error, e.g. report to a service
}
```
app.config.warnHandler example
Example showing warn handler configuration:
```js
app.config.warnHandler = (msg, instance, trace) => {
// `trace` is the component hierarchy trace
}
```
app.config.compilerOptions.isCustomElement example
Example showing custom element detection:
```js
// treat all tags starting with 'ion-' as custom elements
app.config.compilerOptions.isCustomElement = (tag) => {
return tag.startsWith('ion-')
}
```
app.config.compilerOptions.whitespace example
Example showing whitespace preservation:
```js
app.config.compilerOptions.whitespace = 'preserve'
```
app.config.compilerOptions.delimiters example
Example showing custom delimiters:
```js
// Delimiters changed to ES6 template string style
app.config.compilerOptions.delimiters = ['${', '}']
```
app.config.compilerOptions.comments example
Example showing comment preservation:
```js
app.config.compilerOptions.comments = true
```
app.config.optionMergeStrategies example
Example showing custom merge strategy:
```js
const app = createApp({
// option from self
msg: 'Vue',
// option from a mixin
mixins: [
{
msg: 'Hello '
}
],
mounted() {
// merged options exposed on this.$options
console.log(this.$options.msg)
}
})
// define a custom merge strategy for `msg`
app.config.optionMergeStrategies.msg = (parent, child) => {
return (parent || '') + (child || '')
}
app.mount('#app')
// logs 'Hello Vue'
```
app.config.idPrefix example
Example showing ID prefix configuration:
```js
app.config.idPrefix = 'myApp'
```
Inside a component:
```js
const id1 = useId() // 'myApp:0'
const id2 = useId() // 'myApp:1'
```
Production Error Code Reference for error codes
In production, the info argument of errorHandler is a shortened code instead of the full information string. The code to string mapping can be found in the Production Error Code Reference.
app.config.errorHandler default behavior
The default error handler re-throws errors during development and logs errors during production. This can be configured using the throwUnhandledErrorInProduction property.
__VUE_OPTIONS_API__ compile-time flag
__VUE_OPTIONS_API__ is a compile-time flag with a default value of true. It enables or disables Options API support. Disabling this will result in smaller bundles, but may affect compatibility with 3rd party libraries if they rely on Options API.
__VUE_PROD_DEVTOOLS__ compile-time flag
__VUE_PROD_DEVTOOLS__ is a compile-time flag with a default value of false. It enables or disables devtools support in production builds. Enabling this will result in more code included in the bundle, so it is recommended to only enable this for debugging purposes.
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ compile-time flag
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ is a compile-time flag with a default value of false. It enables or disables detailed warnings for hydration mismatches in production builds. Enabling this will result in more code included in the bundle, so it is recommended to only enable this for debugging purposes. This flag is only available in Vue 3.4 and later.
Compile-time flags only apply to esm-bundler build
Compile-time flags only apply when using the esm-bundler build of Vue, which is `vue/dist/vue.esm-bundler.js`. The benefit of using compile-time flags is that features disabled this way can be removed from the final bundle via tree-shaking.
Configuring compile-time flags in Vite
In Vite, @vitejs/plugin-vue automatically provides default values for compile-time flags. To change the default values, use Vite's `define` config option. Example: in vite.config.js, use `define: { __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'true' }`.
Configuring compile-time flags in vue-cli
@vue/cli-service automatically provides default values for some compile-time flags. To configure or change the values, modify vue.config.js using chainWebpack to tap into the 'define' plugin and assign the flags: __VUE_OPTIONS_API__, __VUE_PROD_DEVTOOLS__, and __VUE_PROD_HYDRATION_MISMATCH_DETAILS__.
Configuring compile-time flags in webpack
In webpack, compile-time flags should be defined using webpack's DefinePlugin. Example: new webpack.DefinePlugin({ __VUE_OPTIONS_API__: 'true', __VUE_PROD_DEVTOOLS__: 'false', __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'false' }).
Configuring compile-time flags in Rollup
In Rollup, compile-time flags should be defined using @rollup/plugin-replace. Example: import replace from '@rollup/plugin-replace'; then in plugins array: replace({ __VUE_OPTIONS_API__: 'true', __VUE_PROD_DEVTOOLS__: 'false', __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'false' }).
extends option type
The extends option has type: interface ComponentOptions { extends?: ComponentOptions }. It allows one component to extend another, inheriting its component options.
provide option type and usage
The provide option has type: interface ComponentOptions { provide?: object | ((this: ComponentPublicInstance) => object) }. The provide option should be either an object or a function that returns an object. This object contains the properties that are available for injection into descendant components. You can use Symbols as keys in this object.
provide with object literal example
Example of provide using an object literal:
const s = Symbol()
export default {
provide: {
foo: 'foo',
[s]: 'bar'
}
}
provide with function to provide per-component state
Example of provide using a function to provide per-component state:
export default {
data() {
return {
msg: 'foo'
}
}
provide() {
return {
msg: this.msg
}
}
}
Note: the provided msg will NOT be reactive when provided this way.
inject option type
The inject option has type: interface ComponentOptions { inject?: ArrayInjectOptions | ObjectInjectOptions }. ArrayInjectOptions is string[]. ObjectInjectOptions is { [key: string | symbol]: string | symbol | { from?: string | symbol; default?: any } }.
inject array form usage
The inject option can be an array of strings, where each string is the key to search for in available injections.
Example:
export default {
inject: ['foo'],
created() {
console.log(this.foo)
}
}
inject object form with from and default
The inject option can be an object where keys are local binding names and values can be: a string or Symbol (the key to search for), or an object with optional from property (the key to search for in available injections) and optional default property (fallback value). For object types in default, a factory function is needed to avoid value sharing between multiple component instances.
inject with default value example
Example of inject with default value:
const Child = {
inject: {
foo: { default: 'foo' }
}
}
inject with from property example
Example of inject with from to denote the source property:
const Child = {
inject: {
foo: {
from: 'bar',
default: 'foo'
}
}
}
inject with factory function for object defaults
Example of inject with factory function for non-primitive default values:
const Child = {
inject: {
foo: {
from: 'bar',
default: () => [1, 2, 3]
}
}
}
inject reactivity behavior
Injected bindings are NOT reactive by design. However, if the injected value is a reactive object, properties on that object do remain reactive. An injected property will be undefined if neither a matching property nor a default value was provided.
mixins option type
The mixins option has type: interface ComponentOptions { mixins?: ComponentOptions[] }. It accepts an array of mixin objects that can contain instance options like normal instance objects.
mixins merge and hook order
Mixin objects are merged against the component's options using certain option merging logic. Mixin hooks are called in the order they are provided, and called before the component's own hooks. If your mixin contains a hook like created and the component also has one, both functions will be called.
mixins hook execution order example
Example of mixins hook execution order:
const mixin = {
created() {
console.log(1)
}
}
createApp({
created() {
console.log(2)
},
mixins: [mixin]
})
// Output:
// => 1
// => 2
mixins no longer recommended in Vue 3
In Vue 3, mixins are no longer the primary mechanism for creating reusable chunks of component logic. While mixins continue to be supported, composable functions using Composition API is now the preferred approach for code reuse between components.
extends implementation similarity to mixins
From an implementation perspective, extends is almost identical to mixins. The component specified by extends will be treated as though it were the first mixin. Any options (except for setup()) will be merged using the relevant merge strategy.
extends differs from mixins in intent
The mixins option is primarily used to compose chunks of functionality, whereas extends is primarily concerned with inheritance.
extends not recommended for Composition API
extends is designed for Options API and does not handle the merging of the setup() hook. In Composition API, the preferred mental model for logic reuse is composition over inheritance. If you have logic from a component that needs to be reused in another one, consider extracting the relevant logic into a Composable. If you still intend to extend a component using Composition API, you can call the base component's setup() in the extending component's setup().
extends with Composition API example
Example of extending a component using Composition API:
import Base from './Base.js'
export default {
extends: Base,
setup(props, ctx) {
return {
...Base.setup(props, ctx),
// local bindings
}
}
}