vuejs/vue-rx

Usage with Class based component

psyCodelist opened this issue ยท 10 comments

Hello,

Is there any place that I can see example of integration with Class Based Components?

Many thanks in advance!

@psyCodelist
I believe you can use $subscribeTo method (unfortunately I didn't manage subscriptions() to work properly inside class-based component):

<template>
    <div class="encode">
        <button v-stream:click="click$">Count</button>
        <button @click="clearCounter()">Clear</button>
        <h2 v-if="counter">Clicks: {{counter}}</h2>
    </div>
</template>

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

    @Component
    export default class Encode extends Vue {
        click$ = new Subject();
        counter: number = 0;

        mounted() {
            this.$subscribeTo(
                this.click$
                    .bufferWhen(() => this.click$.debounceTime(500)),
                clicksCount => {
                    this.counter = clicksCount.length;
                })
        }
        clearCounter() {
            this.counter = 0;
        }
    }
</script>
<template>
  <section class="section">
      {{interval$}}
  </section>
</template>

<script>
import { interval } from 'rxjs';
import Vue from 'vue';
import Component from 'vue-class-component';

@Component({
  subscriptions: () => {
    const interval$ = interval(1000);

    return {
      interval$
    }
  }
})
export default class App extends Vue {

}
</script>

This should be work with vue-calss-component

I want to found this solution.. but i don't find that.
so, i made a decorator binding.

https://github.com/MinuKang/vue-rx-decorators

Via the @Componentoptions you can do:

subscriptions() {
    return {
      thing: this.someObservableFromComponent.pipe(
        map(something => {
           return doStuffTo(something);
        }),
      )
    };
  }

Are there any options to use subscriptions with TypeScript?

I've found out that in case of TypeScript the following code works:

@Component<ComponentClass>({
  subscriptions() {
    // this - instance of ComponentClass
    return {
       // actual subscriptions
    }
  }
})
export default class ComponentClass extends Vue {
   // ...
}

@dmdnkv
I'm using the same pattern in a Nuxt JS with typescript project.
The issue I'm having is that even though it works, the IDE (VS Code) is complaining about subscriptions "not being assignable".

Did you have the same issue and did you manage to solve it ?
Screen Shot 2019-04-10 at 16 20 09

@lambda0xff
I use WebStorm from JetBrains and it doesn't complain about subscriptions, I didn't try it in VSCode

I wonder if @MinUKang decorators can be incorporated into Vue-RX

@lambda0xff
you need import vue-rx(but will not use it):

import VueRx from 'vue-rx'

because it covers vue.d.ts, see(vue-rx/types/index.d.ts):

import Vue from 'vue'
import { WatchOptions } from 'vue'
import { Observable } from 'rxjs'

export type Observables = Record<string, Observable<any>>
declare module 'vue/types/options' {
  interface ComponentOptions<V extends Vue> {
    subscriptions?: Observables | ((this: V) => Observables)
    domStreams?: string[]
    observableMethods?: string[] | Record<string, string>
  }
}

export interface WatchObservable<T> {
  newValue: T
  oldValue: T
}
declare module "vue/types/vue" {
  interface Vue {
    $observables: Observables;
    $watchAsObservable(expr: string, options?: WatchOptions): Observable<WatchObservable<any>>
    $watchAsObservable<T>(fn: (this: this) => T, options?: WatchOptions): Observable<WatchObservable<T>>
    $eventToObservable(event: string): Observable<{name: string, msg: any}>
    $subscribeTo<T>(
      observable: Observable<T>,
      next: (t: T) => void,
      error?: (e: any) => void,
      complete?: () => void): void
    $fromDOMEvent(selector: string | null, event: string): Observable<Event>
    $createObservableMethod(methodName: string): Observable<any>
  }
}

export default function VueRx(V: typeof Vue): void