Skip to content

Instantly share code, notes, and snippets.

@anthonygore
Last active June 9, 2021 05:50
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anthonygore/be75c62c65f02f462e94d8d71e45ca8a to your computer and use it in GitHub Desktop.
Save anthonygore/be75c62c65f02f462e94d8d71e45ca8a to your computer and use it in GitHub Desktop.
Vue Composition API + RxJS counter
<template>
<div>
<input v-model="input" type="number" />
<h1>{{ output }}</h1>
</div>
</template>
<script>
import { ref, watch, onUnmounted } from 'vue';
import { timer, Subject } from 'rxjs';
import { takeWhile, map, switchMap, debounceTime } from 'rxjs/operators';
export default {
setup() {
const input = ref(0);
const output = ref(0);
const diff$ = new Subject();
/* Streams input and output values */
const streamDiff = input => {
diff$.next({
start: output.value,
end: parseInt(input)
});
};
watch(input, streamDiff);
const timer$ = timer(0, 25);
/* Will either increment or decrement val based on direction */
const alterValue = (start, end) => val => start + (start < end ? val : -val);
/* Will return true if val has not reached end */
const isDiff = (start, end) => val => start < end ? val <= end : val >= end
/* Updates output value */
const updateOutput = val => output.value = val
const counter$ = diff$.pipe(
debounceTime(500),
switchMap(({ start, end }) => {
return timer$.pipe(
map(alterValue(start,end)),
takeWhile(isDiff(start,end))
)
})
);
counter$.subscribe(updateOutput);
onUnmounted(() => counter$.unsubscribe());
return { input, output }
}
}
</script>
@benlesh
Copy link

benlesh commented Jun 7, 2021

This is really cool. (I don't really use Vue, so this interested me).

It would be cool if you could teach me something about Vue:

On line 50 you're subscribing to counter$ and not keeping the subscription. I presume this is okay, since this will be active for the duration of the application, as the component (or whatever the Vue term is) will never be torn down.

I'd be curious how different this would look if the counter was in a component that was supposed to be added and removed. Like, where would the unsubscribe go?

I'm also curious what ref(0) is here, although I'm sure I can look at the API documentation for that.

@benlesh
Copy link

benlesh commented Jun 7, 2021

Nevermind, I figured out the idioms. Thanks for this example. Pretty cool.

@anthonygore
Copy link
Author

anthonygore commented Jun 8, 2021

Thanks, Ben. I actually forgot to do the unsubscribe, have now updated the gist to do that.

P.S. Credit should also go to this Smart Counter example.

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