使用vue-rx插件將vue和rxjs聯繫起來vue
在main.js中將vue-rx注入vue中ios
import Vue from 'vue' import App from './App' import router from './router' import VueRx from 'vue-rx' // Vue.config.productionTip = false Vue.use(VueRx) /* eslint-disable no-new */ new Vue({ el: '#app', router, components: { App }, template: '<App/>' })
使用 observableMethods 選項聲明observable,也可使用this.$createObservableMethod('muchMore')建立
調用註冊的observable方法muchMore(500),至關於nextx(500)
merge是將多個observable合併起來,統一監聽處理
scan是累計處理git
<template> <div> <div>{{ count }}</div> <button v-on:click="muchMore(500)">Add 500</button> <button v-on:click="minus(minusDelta1)">Minus on Click</button> <pre>{{ $data }}</pre> </div> </template> <script> import { merge } from 'rxjs' import { startWith, scan } from 'rxjs/operators' // 使用 observableMethods 選項聲明observable,也可使用this.$createObservableMethod('muchMore')建立 // 調用註冊的observable方法muchMore(500),至關於nextx(500) // merge是將多個observable合併起來,統一監聽處理 // scan是累計處理 export default { name: 'HelloWorld', data() { return { minusDelta1: -1, minusDelta2: -1 } }, observableMethods: { muchMore: 'muchMore$', minus: 'minus$' }, // equivalent of above: ['muchMore','minus'] subscriptions() { return { count: merge(this.muchMore$, this.minus$).pipe( startWith(0), scan((total, change) => total + change) ) } } } </script>
vue-rx 提供 v-stream讓你向一個 Rx Subject 流式發送 DOM 事件
渲染髮生以前你須要在vm實例上提早註冊數據,好比plus$
傳遞額外參數 傳遞參數github
<template> <div> <div>{{ count }}</div> <button v-stream:click="plus$">+</button> <button v-stream:click="minus$">-</button> </div> </template> <script> import { merge } from 'rxjs' import { map,startWith, scan } from 'rxjs/operators' export default { domStreams: ['plus$', 'minus$'], subscriptions() { return { count: merge( this.plus$.pipe(map(() => 1)), this.minus$.pipe(map(() => -1)) ).pipe( startWith(0), scan((total, change) => total + change) ) } } } </script>
組件觸發父組件流事件
pluck操做符抽取特定的屬性流傳下去axios
<template> <div> <div>{{ count }}</div> <!-- simple usage --> <button v-stream:click="plus$">Add on Click</button> <button v-stream:click="{ subject: plus$, data: minusDelta1, options:{once:true} }" >Add on Click (Option once:true)</button> <!-- you can also stream to the same subject with different events/data --> <button v-stream:click="{ subject: minus$, data: minusDelta1 }" v-stream:mousemove="{ subject: minus$, data: minusDelta2 }" >Minus on Click & Mousemove</button> <pre>{{ $data }}</pre> <my-button v-stream:click="plus$"></my-button> </div> </template> <script> // import { Observable, Subject, ReplaySubject, from, of, range } from 'rxjs'; // import { map, filter, switchMap } from 'rxjs/operators'; import { merge } from 'rxjs' import { map, pluck, startWith, scan } from 'rxjs/operators' export default { data() { return { minusDelta1: -1, minusDelta2: -1 } }, components: { myButton: { template: `<button @click="$emit('click')">MyButton</button>` } }, created() { //Speed up mousemove minus delta after 5s setTimeout(() => { this.minusDelta2 = -5 }, 5000) }, // declare dom stream Subjects domStreams: ['plus$', 'minus$'], subscriptions() { return { count: merge( this.plus$.pipe(map(() => 1)), this.minus$.pipe(pluck('data')) ).pipe( startWith(0), scan((total, change) => total + change) ) } } } </script>
from 從一個數組、類數組對象、Promise、迭代器對象或者類 Observable 對象建立一個 Observable
pluck 將每一個源值(對象)映射成它指定的嵌套屬性。
filter 相似於你們所熟知的 Array.prototype.filter 方法,此操做符從源 Observable 中 接收值,將值傳遞給 predicate 函數而且只發出返回 true 的這些值
debounceTime 只有在特定的一段時間通過後而且沒有發出另外一個源值,才從源 Observable 中發出一個值
distinctUntilChanged 返回 Observable,它發出源 Observable 發出的全部與前一項不相同的項數組
switchMap 將每一個源值投射成 Observable,該 Observable 會合併到輸出 Observable 中, 而且只使用最新投射的Observable中的獲取的值。app
<template> <div> <input v-model="search"> <div v-if="results"> <ul v-if="results.length"> <li :key="match.title" v-for="match in results"> <p>{{ match.title }}</p> <p>{{ match.description }}</p> </li> </ul> <p v-else>No matches found.</p> </div> </div> </template> <script> import axios from 'axios' import { from } from 'rxjs' import { pluck, filter, debounceTime, distinctUntilChanged, switchMap, map } from 'rxjs/operators' let a = 1 //模仿異步返回請求數據 //a=1時,表明第一個返回,5秒以後返回 //a=2時,表明第一個返回,2秒以後返回 //(故意製造,先請求的數據後返回的場景) function fetchTerm(term) { console.log(term, '--') let fetchdata = new Promise((resolve, reject) => { let i = a console.log('發起請求' + i) if (i == 1) { setTimeout(() => { console.log('獲取請求' + i) resolve([ { description: 'description1', title: '第一次的請求' + term + '第' + i + '次' }, { description: 'description2', title: '第一次的請求p' + term + '第' + i + '次' } ]) }, 5000) } else { setTimeout(() => { console.log('獲取請求' + i) resolve([ { description: 'description1', title: '第二次的請求' + term + '第' + i + '次' }, { description: 'description2', title: '第二次的請求p' + term + '第' + i + '次' } ]) a = 0 }, 2000) } }) a = a + 1 console.log('ppp') return from(fetchdata) } function formatResult(res) { console.log(res) return res.map(obj => { return { title: obj.title + 'ooo', description: obj.description + 'ppp' } }) } export default { data() { return { search: '' } }, subscriptions() { return { // this is the example in RxJS's readme. results: this.$watchAsObservable('search').pipe( pluck('newValue'), map(a => { console.log(a) return a }), filter(text => text.length > 2), debounceTime(500), distinctUntilChanged(), switchMap(fetchTerm), //異步請求,先請求的可能後到。解決這個問題 map(formatResult) ) } } } </script>
案例下載dom
vue_rx文檔 異步