Vue Mixin Decorator
This library provides decorators for applying Vue 2 mixins within a TypeScript codebase, specifically designed for use with `vue-class-component`. It allows developers to compose reusable functionalities into class-style Vue components using decorator syntax, enhancing type safety compared to traditional mixin usage. The current stable version is 1.2.0, with the last release in July 2019, indicating a halted development cadence. Key differentiators include its focus on TypeScript and decorators for Vue 2 mixin composition, drawing inspiration from `av-ts` and `vue-property-decorator`. The project explicitly states a hope for deprecation if its core functionality is absorbed by officially supported projects, suggesting it's not intended for long-term standalone development.
Common errors
-
TypeError: Decorator @Mixin is not a function
cause TypeScript decorators are not properly enabled in your `tsconfig.json` or you're missing `reflect-metadata`.fixEnsure `experimentalDecorators` and `emitDecoratorMetadata` are set to `true` in `tsconfig.json`. Also, import `reflect-metadata` once at the entry point of your application: `import 'reflect-metadata';`. -
Property 'mixinMethod' does not exist on type 'MyComponent'.
cause TypeScript is not correctly inferring types from the mixed-in class, or the `Mixins` helper is used incorrectly.fixEnsure the generic type argument for `Mixins<IMyMixinInterface>(MyMixin)` correctly defines the interface that extends all mixed-in classes (e.g., `interface IMyMixinInterface extends MyMixin, MyOtherMixin {}`). -
Cannot find module 'vue-mixin-decorator' or its corresponding type declarations.
cause The package is not installed, or TypeScript cannot find its declaration files.fixRun `npm install --save-dev vue-mixin-decorator` or `yarn add --dev vue-mixin-decorator`. Ensure TypeScript is configured to include `node_modules/@types` or that the package ships its own types. -
[Vue warn]: Unknown custom element: <my-component> - did you register the component correctly?
cause The Vue component defined with `@Component` is not registered globally or locally within its parent component.fixGlobally register the component using `Vue.component('my-component', MyComponent)` or locally within another component's `components` option.
Warnings
- breaking The `v1.0.0` release was marked as 'BREAKING NEWS! Ready for v1' in its changelog, but specific breaking changes were not detailed. Users upgrading from pre-1.0 versions should review the underlying `vue-class-component` changes.
- gotcha This library is built for Vue 2 and `vue-class-component`. It is NOT compatible with Vue 3, which has largely moved away from class-style components and decorators in favor of the Composition API and `defineComponent` or `vue-facing-decorator` for class-style component system.
- gotcha The peer dependency for `typescript` is `>= 2 < 4`. Using TypeScript 4.x or newer with this package may lead to compilation errors or unexpected behavior due to breaking changes in TypeScript's decorator implementation or type inference.
- deprecated The project's README explicitly states that the 'best case scenario is this project/implementation/concept gets merged/provided into/by an officially supported project and this one can be deprecated.' This indicates the project maintainers do not intend for long-term independent development. It has not been updated since 2019.
- gotcha Vue 3 changed the data option declaration to always expect a function, and when merging multiple data return values from mixins, the merge is now shallow instead of deep. This library's behavior, tied to Vue 2's deep merge, would be incompatible with Vue 3's approach if it were to be used.
Install
-
npm install vue-mixin-decorator -
yarn add vue-mixin-decorator -
pnpm add vue-mixin-decorator
Imports
- Mixin
const Mixin = require('vue-mixin-decorator').Mixin;import { Mixin } from 'vue-mixin-decorator'; - Component
import Component from 'vue-mixin-decorator';
import { Component } from 'vue-mixin-decorator'; - Mixins
import { mixins } from 'vue-mixin-decorator';import { Mixins } from 'vue-mixin-decorator';
Quickstart
import Vue from 'vue';
import { Component, Mixin, Mixins } from 'vue-mixin-decorator';
// Define a mixin using the @Mixin decorator
@Mixin
class MyMixin extends Vue {
message: string = 'Hello from Mixin!';
created() {
console.log('Mixin created hook fired. Message:', this.message);
}
mixinMethod() {
console.log('Mixin method called. Message:', this.message);
}
}
// Define a component that extends the mixin using Mixins helper
@Component
class MyComponent extends Mixins<MyMixin>(MyMixin) {
created() {
// Access mixin properties and methods directly
this.mixinMethod();
console.log('Component created hook fired. Mixin message:', this.message);
}
render(h) {
return h('div', `Component Output: ${this.message}`);
}
}
// Instantiate and mount the component
new MyComponent().$mount('#app');