Skip to content

Instantly share code, notes, and snippets.

@acoshift
Created August 9, 2017 14:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save acoshift/a1671af08bec653e3c2940bd23a151c0 to your computer and use it in GitHub Desktop.
Save acoshift/a1671af08bec653e3c2940bd23a151c0 to your computer and use it in GitHub Desktop.
Vue + Vue-Rx
<template>
<div id="app">
<input ref="q">
<button v-stream:click="q$">Search</button>
<div>
<h1>{{ topic }} ({{ page }} / {{ totalPage }})</h1>
<select v-stream:change="perPage$">
<option :value="10">10</option>
<option :value="15">15</option>
<option :value="20">20</option>
</select>
<br>
<button v-stream:click="prevClick$">Prev</button>
<button v-stream:click="nextClick$">Next</button>
<h2 v-if="loading">Loading...</h2>
<ul>
<li v-for="x in list" :key="x">{{ x }}</li>
</ul>
</div>
</div>
</template>
<script>
import { Observable, Subject, BehaviorSubject } from 'rxjs'
import axios from 'axios'
const searchGithub = (q, page, perPage) => Observable.fromPromise(
axios.get('https://api.github.com/search/repositories', {
params: {
q,
page,
per_page: perPage
}
}))
.map((resp) => resp.data)
export default {
name: 'app',
domStreams: ['q$', 'prevClick$', 'nextClick$', 'perPage$'],
subscriptions () {
const page$ = new Subject()
const loading$ = new BehaviorSubject(false)
const q$$ = this.q$
.map(() => this.$refs.q.value)
.do(() => { page$.next(1) })
const page$$ = Observable.merge(
page$,
this.prevClick$.map(() => this.page - 1),
this.nextClick$.map(() => this.page + 1)
)
.filter((page) => page > 0 && page <= this.totalPage)
.startWith(1)
const perPage$$ = this.perPage$
.map((e) => +e.event.target.value)
.startWith(10)
const search$ = Observable.combineLatest(
q$$,
page$$,
perPage$$,
)
.debounceTime(1)
.map(([q, page, perPage]) => ({ q, page, perPage }))
.flatMap((x) => loading$.first(), (x, loading) => ({...x, loading}))
.filter(({ loading }) => !loading)
.do(() => { loading$.next(true) })
.flatMap(({ q, page, perPage }) =>
searchGithub(q, page, perPage),
({ q, page, perPage }, data) => ({
q,
page,
perPage,
list: data.items,
total: data.total_count
}))
.do(() => { loading$.next(false) })
.share()
return {
list: search$
.pluck('list')
.map((list) => list.map((x) => x.full_name)),
topic: search$
.pluck('q'),
total: search$
.pluck('total'),
totalPage: search$
.map((resp) => Math.ceil(resp.total / resp.perPage))
.startWith(0),
page: search$
.pluck('page')
.startWith(1),
loading: loading$
}
}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment