vuejs / vue-class-component

ES / TypeScript decorator for class-style Vue components.
MIT License
5.81k stars 429 forks source link

[BUG] Metadata defined on a component can't be retreived from a mixin #536

Open amura11 opened 3 years ago

amura11 commented 3 years ago

I wanted to create a decorator that would add metadata to my class component then be able to pull that metadata out using a mixin and the beforeCreate hook (I'm not sure if that's the right term). However, when the method runs and I try to get the metadata the metadata isn't there. Looking at the source for this library I saw a function that looks like it would copy the metadata (this file) which makes me think it should be possible.

Code My code is much more complex than this but it boils down to essentially this:

const metadataKey: string = "myMetadataKey";

function MyDecorator(token: string) {
    return (target: any, property: string) => {
        Reflect.defineMetadata(metadataKey, token, target);
    };
}

@Component
export default class MyView extends Vue {

    @MyDecorator("test")
    private myProperty!: string;
}

Vue.mixin({
    beforeCreate() {
        console.log(Reflect.getMetadata(metadataKey, this)); //This doesn't work for me
    }
});

Is this something I can even achieve?

P.S. I'm not sure if this is even related to this library or Vue itself, this seemed like the best place to start

amura11 commented 3 years ago

I still haven't been able to find a solution to this so I created a test project that recreates the issue with a minimal amount of code. The test project can be found here.

While testing this I stepped through the code and found that at this line if I call Reflect.getMetadataKeys(Component.prototype) I see my metadata key there.

~I may be wrong about this but is it possible that the metadata on the prototype should also be copied in the copyReflectionMetadata method?~

Edit

I decided to throw a breakpoint just at the beginning of copyReflectionMetadata and call forwardMetadata(to.prototype, from.prototype) to see what would happen. When I did that, my code worked as expected.

Is there a reason for not doing this in copyReflectionMetadata that I'm missing?