Use plugin given Vue constructor for component inheritance with vue-component-class

1.2k Views Asked by At

I have a plugin that create multiple globally available components, these components access instance properties set by other plugins in the main app. In most Typescript examples, people get their Vue constructor by import { Vue } from 'vue' or import { Vue } from 'vue-property-decorator'however I'd like to use the vue constructor that is passed down to my plugin. How would you do that?

Here is my attempt which does not work sadly. I know it works without using classes but that's not the point.

// app/main.ts

import Vue from 'vue';
import Vuetify from 'vuetify';
import { MyComponentsPlugin } from 'my-components-plugin';

import App from './App';

Vue.use(Vuetify);
Vue.use(MyComponentsPlugin);

new Vue({
  render: h => h(App)
});
// my-components-plugin/main.ts

import { VueConstructor } from 'vue';

import MyComponentExport from './components/MyComponent/Component.vue';

export async function MyComponentsPlugin(
  vue: VueConstructor,
  options?: any,
): Promise<void> {
  vue.component('MyComponent', MyComponentExport(vue));
}
// my-components-plugin/components/Component.vue

<template>
  <p>toto</p>
</template>

<script lang="ts">
import { VueConstructor } from 'vue';
import { Component, Prop } from 'vue-property-decorator';

export default function(Vue: VueConstructor) {
 @Component
  class Header extends Vue {
    private mounted() {
      console.log(this.$vuetify);
    }
  }

  return Header;
}
</script>

<style></style>
1

There are 1 best solutions below

0
On

To solve this issue, you need to update your webpack config in your vue.config.js. Add:

const path = require('path');

module.exports = {
  configureWebpack: config => {
    if (process.env.NODE_ENV === 'development') {
      config.resolve.modules.prepend(path.resolve(__dirname, './node_modules'));
    }
  },
};

This way your project dependencies will search first into your project local node_modules to find their dependencies hence they will use the same Vue as the main application.

We don't need to add it for production environment because the bundles will be optimized and Vue code duplication will be prevented.