karol-f / vue-custom-element

Vue Custom Element - Web Components' Custom Elements for Vue.js
https://karol-f.github.io/vue-custom-element/
MIT License
1.97k stars 187 forks source link

Cannot wrap Vue component using typescript and vue-property-decorator #219

Closed sepharg closed 4 years ago

sepharg commented 4 years ago

We´re using vue-property-decorator to implement our Vue components, having decorators such as @Prop, @Component, etc For example, a simple button:

<template>
    <div :class="getClassList" @click="btnClick">
        <slot></slot>
    </div>
</template>

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

export default class Btn extends Vue {
    @Prop({ default: 'flat-maincolor' }) public readonly type!: string;
    @Prop({ default: false }) public readonly disabled!: boolean;

    get getClassList(): string[] {
      const auxList = [];
      auxList.push('button');
      auxList.push(this.type);
      if (this.disabled) {
        auxList.push('disabled');
      }
      return auxList;
    }

    public btnClick() {
      if (!this.disabled) {
        this.$emit('btnClick');
      }
    }

}
</script>

When trying to encapsulate this component in a web-component ,we get the following runtime error and aren't able to get past it:

    vue.esm.js?a026:5157 Uncaught TypeError: Cannot read property '_init' of undefined
    at Btn (vue.esm.js?a026:5157)
    at HTMLElement.connectedCallback (vue-custom-element.esm.js?c894:484)
    at HTMLElement.connectedCallback (vue-custom-element.esm.js?c894:57)
    at Object.insertBefore (vue.esm.js?a026:5714)
    at insert (vue.esm.js?a026:6044)
    at createComponent (vue.esm.js?a026:5991)
    at createElm (vue.esm.js?a026:5930)
    at Vue.patch [as __patch__] (vue.esm.js?a026:6521)
    at Vue._update (vue.esm.js?a026:3948)
    at Vue.updateComponent (vue.esm.js?a026:4069)

Is it something that we're missing, or vue-custom-element just doesn't support these custom attributes in typescript?

karol-f commented 4 years ago

Hi, can You show me the code how You define custom element?

sepharg commented 4 years ago

Sure thing, here´s the import:

import vueCustomElement from 'vue-custom-element'
import Btn from './components/Btn.vue';
Vue.use(vueCustomElement);
Vue.customElement('my-btn', Btn);

And then in App.Vue

<template>
  <div id="app">
    <main>
      <my-btn>I AM A BUTTON</my-btn>
    </main>
  </div>
</template>
karol-f commented 4 years ago

Hi, vue-class-component return constructor so we have to use little hack. Just change one line during custom element definition:

Vue.customElement('my-btn', Btn.prototype.constructor.options);

Regards.

sepharg commented 4 years ago

thanks a lot, that works!