Skip to content

Mixin and @Watch won't watch #119

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
304NotModified opened this issue Jul 3, 2017 · 11 comments
Closed

Mixin and @Watch won't watch #119

304NotModified opened this issue Jul 3, 2017 · 11 comments

Comments

@304NotModified
Copy link
Contributor

304NotModified commented Jul 3, 2017

It seems that the @Watch isn't working when using mixins as described in #91.

The @watch works in the mixin, but not in the class that is using the mixin.

In the following example:

  • watching test1 works
  • watching test2 wont work. Is the the property is reactive, but it's not listed in _watchers and not in _computedWatchers.

Is there something I could do to fix this? It's a showstopper for me for using Mixins. Thanks in advance!

@JsonSong89 any idea?

NB the @Watch is from vue-property-decorator

@Component
class Apple extends Vue {

   string test1 = null;

    @Watch("test1")
    test1Changed(): void { // <-------- works
        console.log("test1 changed")
    }
}


interface IApple extends Apple {

}

// compiles under TS2.2
@ComponentForMixin({
    template: `<span @click="Uh"> click show</span>`
})
export default class Component1 extends Mixin<IApple>(Apple) {
    string test2 = null;

    @Watch("test2")
    test2Changed(): void { // <-------- WONT work
        console.log("test2 changed")
    }
}
@304NotModified 304NotModified changed the title Mixin and @Watch Mixin and @Watch won't watch Jul 3, 2017
@304NotModified
Copy link
Contributor Author

304NotModified commented Jul 3, 2017

debugging now:

@Watch is using createDecorator, and it looks like createDecorator is never called.

@304NotModified
Copy link
Contributor Author

I think the issue is in https://github.com/vuejs/vue-class-component/blob/master/src/component.ts

the decorators aren't called for all the decorators

@304NotModified
Copy link
Contributor Author

I think this is #104

Unfortunately npm5 is buggy, as I was under the impression that I was using the latest version, but currently 4.4. is installed. Can't get npm update working atm.

@304NotModified
Copy link
Contributor Author

case closed until I have proper tested with 5.0.2

@304NotModified
Copy link
Contributor Author

unfortunately this is also an issue with 5.0.2 :(

@304NotModified
Copy link
Contributor Author

__decorators__ is undefined. Any hints where I should look?

image

@ktsn
Copy link
Member

ktsn commented Jul 3, 2017

Could you provide self-contained reproduction with github repo or jsfiddle?

@ktsn ktsn added the need repro label Jul 3, 2017
@JsonSong89
Copy link

JsonSong89 commented Jul 4, 2017

@304NotModified sorry , my fault.
I did't use Component from official , because the official only support VueClass

https://github.com/vuejs/vue-class-component/blob/master/src/index.ts

import Vue, { ComponentOptions } from 'vue';
import { VueClass } from './declarations';
export { createDecorator } from './util';
declare function Component<U extends Vue>(options: ComponentOptions<U>): <V extends VueClass>(target: V) => V;
declare function Component<V extends VueClass>(target: V): V;
declare namespace Component {
    function registerHooks(keys: string[]): void;
}
export default Component;

but Mixin need a wrap to contain the mixined interface

type VClass<T extends Vue> = {
    new(): T
    extend(option: ComponentOptions<Vue> | FunctionalComponentOptions): typeof Vue
}

So I implement the Component again ,add type support for VClass and name it ComponentForMixin , maybe the componentFactory method will check whether it is instance of official Component .

I just use the official Component and test again,it has a ts type error,but it can works now.

@HerringtonDarkholme
I think the better way is extend official Component , maybe you can create a pr?

@JsonSong89
Copy link

I am also a fresh for TypeScript , look like there is a way to extend a namespace out .
maybe we can try this .

@ktsn
also , I think the Minix from av-ts is a great design , would you think about add this feature ?

@JsonSong89
Copy link

@304NotModified
Now you have two ways to solve it

  1. edit /node_modules/vue-class-component/lib/index.d.ts
    change to declare function Component(options: ComponentOptions): (target: V) => V;

declare function Component<U extends Vue>(options: ComponentOptions<U>, str: string): <V extends VClass<U>>(target: V) => V;
declare namespace Component {
}
// compiles under TS2.2
@Component({
    template: `<span @click="Uh"> click show</span>`
}, "")

there are both not a grace way , maybe the first is acceptable .

in fact , this type error has not real effect .

I will keep thinking and learning ...

@304NotModified
Copy link
Contributor Author

304NotModified commented Jul 4, 2017

Hi @JsonSong89

thanks

But unfortunately the issue why on my side. I had a dependency hell with NPM.

I found out I had 2 times vue-class-component in node_modules (5.0.2), one at top level and one at node_modules/vue-property-decorator/node_modules/ (5.0.1)

In my package.json both packages where listed only once:

    "vue-class-component": "^5.0.2",
    "vue-property-decorator": "^5.1.0",

This was caused by package-lock.json, and I don't now why. It had this in the lock file:

image

I removed the npm lock file, removed the node_modules folder and after npm install it worked.

Thanks for the support, sorry for the inconvenience.

Concluding: fixed in 5.0.2 with #104

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants