DEV Community

Cover image for Rx Composition Api [Vue 3 | RxJS]
NOPR9D ☄️
NOPR9D ☄️

Posted on • Edited on

6 4

Rx Composition Api [Vue 3 | RxJS]

edit: you can use this package i made https://www.npmjs.com/package/@nopr3d/vue-next-rx

Hi !

Vue 3 is here, is fresh but we have to wait for our preferred dependences.

So vue-rx work only with Vue 2 and I think you are wondering how we can use rxjs with the new version of vue? (I'm)


So, this is how we can extend the composition Api

Ref
import { Observer, Observable, Subject } from "rxjs";
import { onBeforeUnmount, ref as _ref, Ref as _Ref, watch } from "vue";

export type Ref<T = any> = _Ref<T> & Observer<T> & Observable<T>;

export function ref(value?: unknown): Ref {
  const $ref = _ref(value) as Ref;
  const subject = new Subject();

  // extend your ref to rx and bind context
  $ref.next = subject.next.bind(subject);
  $ref.pipe = subject.pipe.bind(subject);
  $ref.subscribe = subject.subscribe.bind(subject);



  watch($ref, (val) => {
    subject.next(val);
  });

  // Don't forget to unsubscribe or you will get memory leaks
  onBeforeUnmount(() => subject.unsubscribe()); 
  return $ref;
}
Enter fullscreen mode Exit fullscreen mode

Watch
import {
  watch as _watch,
  WatchStopHandle as _WatchStopHandle,
} from "vue";

export type WatchStopHandle<T = any> = Observer<T> &
  Observable<T> &
  (() => void);

export function watch(ref: Ref, fn?: (val: any) => any): WatchStopHandle {

  const subject = new Subject();
  const $watch = _watch(ref, (val) => {
    subject.next(val);
    if (fn) fn(val);
  }) as WatchStopHandle;

  $watch.next = subject.next.bind(subject);
  $watch.pipe = subject.pipe.bind(subject);
  $watch.subscribe = subject.subscribe.bind(subject);

  onBeforeUnmount(() => subject.unsubscribe());

  return $watch;
}
Enter fullscreen mode Exit fullscreen mode

So we can use the return of our composition function like any usual observable.

// Create your own vue folder, store your custom api here
import { ref, watch } from "@/vue";

export default {
  name: "App",
  setup() {
    const tick = ref(0);

    setInterval(() => {
      tick.value++;
    }, 1000);

    // subscribe and do something at every change

    // With Ref
    tick.subscribe((value)=>{console.log(value)}); 

   // With Watch
    watch(tick)
        .pipe(map((val) => val * 1000))
        .subscribe(console.log);

    return { tick };
  },
};

Enter fullscreen mode Exit fullscreen mode

Demo :

Alt Text

AWS GenAI LIVE image

How is generative AI increasing efficiency?

Join AWS GenAI LIVE! to find out how gen AI is reshaping productivity, streamlining processes, and driving innovation.

Learn more

Top comments (2)

Collapse
 
oceangravity profile image
Juan Carlos Galindo Navarro

What about watchEffect, watch?
v3.vuejs.org/api/computed-watch-ap...

Collapse
 
noprod profile image
NOPR9D ☄️ • Edited

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay