Last active
June 9, 2021 05:50
-
-
Save anthonygore/be75c62c65f02f462e94d8d71e45ca8a to your computer and use it in GitHub Desktop.
Vue Composition API + RxJS counter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
Nevermind, I figured out the idioms. Thanks for this example. Pretty cool.
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
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.