Vue 3 compatibility build for Vue 2 that provides configurable Vue 2 compatible behavior to facilitate migration from Vue 2 to Vue 3
—
Fine-grained compatibility feature management with global and per-component configuration options. Control exactly which Vue 2 behaviors to maintain and which to migrate to Vue 3.
Configure global compatibility options for the entire application.
/**
* Configure global compatibility options
* @param config - Compatibility configuration object
*/
function configureCompat(config: CompatConfig): void;
type CompatConfig = Partial<Record<DeprecationTypes, boolean | 'suppress-warning'>> & {
MODE?: 2 | 3 | ((comp: Component | null) => 2 | 3);
};Usage Examples:
import { configureCompat } from "@vue/compat";
// Default to Vue 2 mode, disable specific warnings
configureCompat({
MODE: 2,
GLOBAL_MOUNT: false,
INSTANCE_EVENT_EMITTER: false
});
// Default to Vue 3 mode, enable only specific Vue 2 features
configureCompat({
MODE: 3,
GLOBAL_EXTEND: true,
INSTANCE_LISTENERS: true
});
// Dynamic mode per component
configureCompat({
MODE: (comp) => {
// Use Vue 2 mode for legacy components
return comp && comp.name.startsWith('Legacy') ? 2 : 3;
}
});
// Suppress warnings without disabling features
configureCompat({
GLOBAL_PROTOTYPE: 'suppress-warning',
CONFIG_IGNORED_ELEMENTS: 'suppress-warning'
});Controls the default behavior mode for the application.
/**
* Compatibility mode configuration
* - 2: Vue 2 mode (default) - Most APIs behave like Vue 2
* - 3: Vue 3 mode - All APIs behave like Vue 3 unless explicitly enabled
* - Function: Dynamic mode based on component
*/
MODE?: 2 | 3 | ((comp: Component | null) => 2 | 3);Each compatibility feature can be configured with specific values:
/**
* Feature flag values
* - true: Enable the compatibility behavior
* - false: Disable the compatibility behavior (Vue 3 mode)
* - 'suppress-warning': Enable compatibility but suppress warnings
*/
type FeatureFlagValue = boolean | 'suppress-warning';Complete list of compatibility features that can be individually controlled:
enum DeprecationTypes {
/** new Vue() -> createApp() */
GLOBAL_MOUNT = 'GLOBAL_MOUNT',
/** Mounted application container behavior */
GLOBAL_MOUNT_CONTAINER = 'GLOBAL_MOUNT_CONTAINER',
/** Vue.extend -> defineComponent */
GLOBAL_EXTEND = 'GLOBAL_EXTEND',
/** Vue.prototype -> app.config.globalProperties */
GLOBAL_PROTOTYPE = 'GLOBAL_PROTOTYPE',
/** Vue.set removal */
GLOBAL_SET = 'GLOBAL_SET',
/** Vue.delete removal */
GLOBAL_DELETE = 'GLOBAL_DELETE',
/** Vue.observable -> reactive */
GLOBAL_OBSERVABLE = 'GLOBAL_OBSERVABLE',
/** Vue.util deprecation */
GLOBAL_PRIVATE_UTIL = 'GLOBAL_PRIVATE_UTIL',
}enum DeprecationTypes {
/** config.silent removal */
CONFIG_SILENT = 'CONFIG_SILENT',
/** Build-time devtools flag */
CONFIG_DEVTOOLS = 'CONFIG_DEVTOOLS',
/** config.keyCodes removal */
CONFIG_KEY_CODES = 'CONFIG_KEY_CODES',
/** config.productionTip removal */
CONFIG_PRODUCTION_TIP = 'CONFIG_PRODUCTION_TIP',
/** config.ignoredElements -> isCustomElement */
CONFIG_IGNORED_ELEMENTS = 'CONFIG_IGNORED_ELEMENTS',
/** Whitespace handling changes */
CONFIG_WHITESPACE = 'CONFIG_WHITESPACE',
/** Option merge strategy changes */
CONFIG_OPTION_MERGE_STRATS = 'CONFIG_OPTION_MERGE_STRATS',
}enum DeprecationTypes {
/** vm.$set removal */
INSTANCE_SET = 'INSTANCE_SET',
/** vm.$delete removal */
INSTANCE_DELETE = 'INSTANCE_DELETE',
/** vm.$destroy changes */
INSTANCE_DESTROY = 'INSTANCE_DESTROY',
/** Event system changes ($on, $off, $once) */
INSTANCE_EVENT_EMITTER = 'INSTANCE_EVENT_EMITTER',
/** Event hook changes */
INSTANCE_EVENT_HOOKS = 'INSTANCE_EVENT_HOOKS',
/** vm.$children deprecation */
INSTANCE_CHILDREN = 'INSTANCE_CHILDREN',
/** vm.$listeners deprecation */
INSTANCE_LISTENERS = 'INSTANCE_LISTENERS',
/** Scoped slots changes */
INSTANCE_SCOPED_SLOTS = 'INSTANCE_SCOPED_SLOTS',
/** Attribute inheritance changes */
INSTANCE_ATTRS_CLASS_STYLE = 'INSTANCE_ATTRS_CLASS_STYLE',
}enum DeprecationTypes {
/** Data function changes */
OPTIONS_DATA_FN = 'OPTIONS_DATA_FN',
/** Data merging changes */
OPTIONS_DATA_MERGE = 'OPTIONS_DATA_MERGE',
/** beforeDestroy -> beforeUnmount */
OPTIONS_BEFORE_DESTROY = 'OPTIONS_BEFORE_DESTROY',
/** destroyed -> unmounted */
OPTIONS_DESTROYED = 'OPTIONS_DESTROYED',
}enum DeprecationTypes {
/** Array watching changes */
WATCH_ARRAY = 'WATCH_ARRAY',
/** Props default this context */
PROPS_DEFAULT_THIS = 'PROPS_DEFAULT_THIS',
/** Keycode modifier deprecation */
V_ON_KEYCODE_MODIFIER = 'V_ON_KEYCODE_MODIFIER',
/** Custom directive changes */
CUSTOM_DIR = 'CUSTOM_DIR',
/** Attribute false value handling */
ATTR_FALSE_VALUE = 'ATTR_FALSE_VALUE',
/** Attribute coercion changes */
ATTR_ENUMERATED_COERCION = 'ATTR_ENUMERATED_COERCION',
/** Transition class changes */
TRANSITION_CLASSES = 'TRANSITION_CLASSES',
/** TransitionGroup root element */
TRANSITION_GROUP_ROOT = 'TRANSITION_GROUP_ROOT',
/** Async component changes */
COMPONENT_ASYNC = 'COMPONENT_ASYNC',
/** Functional component changes */
COMPONENT_FUNCTIONAL = 'COMPONENT_FUNCTIONAL',
/** v-model component changes */
COMPONENT_V_MODEL = 'COMPONENT_V_MODEL',
/** Render function changes */
RENDER_FUNCTION = 'RENDER_FUNCTION',
/** Filter deprecation */
FILTERS = 'FILTERS',
/** Private API access */
PRIVATE_APIS = 'PRIVATE_APIS',
}Components can override global compatibility settings using the compatConfig option:
interface ComponentOptions {
/**
* Per-component compatibility configuration
* Overrides global settings for this component only
*/
compatConfig?: CompatConfig;
}Usage Examples:
// Legacy component using Vue 2 mode
export default {
name: 'LegacyComponent',
compatConfig: {
MODE: 2,
INSTANCE_LISTENERS: true,
INSTANCE_CHILDREN: true
},
data() {
return { count: 0 };
},
mounted() {
// Access legacy properties
console.log(this.$listeners);
console.log(this.$children);
}
};
// Modern component using Vue 3 mode
export default {
name: 'ModernComponent',
compatConfig: {
MODE: 3
},
setup() {
// Use Vue 3 Composition API
const count = ref(0);
return { count };
}
};
// Hybrid component with specific feature flags
export default {
name: 'HybridComponent',
compatConfig: {
MODE: 3,
INSTANCE_EVENT_EMITTER: true, // Still use $on/$off
GLOBAL_MOUNT: 'suppress-warning' // Keep compatibility, no warnings
}
};Vue 2 global configuration properties (deprecated but supported):
interface LegacyConfig {
/** Suppress all Vue logs and warnings */
silent?: boolean;
/** Enable devtools in production */
devtools?: boolean;
/** Ignore custom elements */
ignoredElements?: (string | RegExp)[];
/** Custom key codes for v-on */
keyCodes?: Record<string, number | number[]>;
/** Show production tip */
productionTip?: boolean;
}Usage Example:
import Vue from "@vue/compat";
// Configure legacy options (deprecated)
Vue.config.silent = false;
Vue.config.devtools = true;
Vue.config.ignoredElements = ['custom-element'];
Vue.config.keyCodes = {
'media-play-pause': 179
};For build-time compatibility features, configure through bundler options:
// Vue CLI configuration
module.exports = {
chainWebpack: config => {
config.resolve.alias.set('vue', '@vue/compat');
config.module
.rule('vue')
.use('vue-loader')
.tap(options => ({
...options,
compilerOptions: {
compatConfig: {
MODE: 2,
COMPILER_V_IF_V_FOR_PRECEDENCE: false
}
}
}));
}
};Install with Tessl CLI
npx tessl i tessl/npm-vue--compat