1、 本文章不會對RxJS的原理進行講解,僅討論如何在vue中對RxJS進行集成
一、30天精通 RxJS
這是一個臺灣開發者編寫的關於RxJS的教程,教程涉及到原理解析、簡易實現,以及經常使用operator的介紹。
二、學習RxJS operator
各類經常使用操做符的做用與例子,能夠結合RxJS的官方文檔進行查閱。
2、Vue簡單集成RxJS 想要在Vue中使用RxJS,只須要以下引用便可,固然,更多引用方法能夠參考官方文檔,好比按需引入php
import Rx from 'rxjs/Rx' 若是你想在vue中使用RxJS的體驗更好,這裏推薦使用vue-rx這個官方維護的庫,使用以下: import Vue from 'vue' import VueRx from 'vue-rx' import Rx from 'rxjs/Rx' Vue.use(VueRx, Rx)
這樣,在Vue實例當中就會多了subscriptions這個鉤子函數,他的用法相似data,使用以下所示:vue
<template> <div> <span>姓名:{{ name$ }}</span> <span>年齡:{{ age$ }}</span> <button v-stream:click="setName$">點擊設置name的值</button> </div> </template> <script> export default { domStreams: [ 'setName$' ], subscriptions () { return { age$: Rx.Observable.of(23) .map(data => data), name$: this.setName$ .map(e => 'myName') .startWith('') } } } </script>
如上所示,Rx.Observable.of(23)在被訂閱時會被髮出值23,this.setName$則是一個流事件,它在domStreams中定義,實際它是一個Subject(具體可查閱RxJS中對Subject的定義),在用戶點擊按鈕的時候則會發出該點擊源的數據,如上圖的map operator中,會接收數據源發出的event對象(這裏咱們沒有使用該對象,僅僅是返回一個咱們定義的字符串'myName'),startWith則是初始化name$的值爲空字符串,這裏vue-rx已經幫咱們作了一個隱式的subscribe綁定,因此值23會立刻發出最後賦值到age$上,進而綁定到視圖,在這裏,咱們能夠把age$與name$當作是一個有數據源發出的可觀察流的結果,這條流是響應的,初始發出的值會通過各類operator處理後響應到頁面上。
3、集成vue-rx後使用RxJS github地址
該項目採起了parcel構建、示例包括原生使用與集成vue-rx後使用的對比、事件如何使用、以及經常使用operator的示例(包含switchMap、concatMap、exhaustMap等的使用場景選擇)
一、建立Observeblegit
<template> <div> <h3>demo2 建立將數據轉化成Observable方式</h3> <p>字符串:{{ str$ }}</p> <p> 數組: <span v-for="(num, index) in arr$" :key="index">{{ num }}</span> </p> <p>對象:{{ obj$.a }}</p> <p>布爾值:{{ bool$ }}</p> <p>promise:{{ promise$ }}</p> <p>interval: {{ interval$ }}</p> </div> </template> <script> import Rx from 'rxjs/Rx' export default { subscriptions () { return { /** * 普通數據類型均可以用of進行轉換 * promise對象可用from或者fromPromise * interval可在給定時間區間內發出自增數字 */ str$: Rx.Observable.of('str'), arr$: Rx.Observable.of([1, 2, 3]), obj$: Rx.Observable.of({ a: 'test-obj' }), bool$: Rx.Observable.of(true), promise$: Rx.Observable.fromPromise(this.getPromise()), interval$: Rx.Observable.interval(1000) } }, methods: { getPromise () { return new Promise((resolve, reject) => { setTimeout(() => { resolve('promise') }, 1000) }) } } } </script>
建立數據流後,用法相似data,可將數據流的結果跟視圖進行綁定
二、事件的使用github
// 沒有集成vue-rx export default { ... // 須要獲取dom,因此必須是mounted後執行才能成功 mounted () { // fromEvent能夠將dom綁定事件並轉化成Observable可觀察對象 Rx.Observable.fromEvent(this.$refs['btn'], 'click') .subscribe(e => { this.data = '成功獲取data' }) }, ... } // 集成vue-rx後 <template> <button class="btn" v-stream:click="getData$">點擊獲取數據</button> </template> <script> export default { ... // v-stream事件能夠統一寫在這裏,具體能夠看vue-rx的使用 domStreams: [ 'getData$' ], subscriptions () { return { data$: this.getData$ // map操做符主要用於映射數據,這裏咱們直接返回了一個字符串 .map(e => { return '成功獲取data' }) } } } </script>
三、switchMap、concatMap、exhaustMap使用 通常這幾個operator,會與http請求結合使用,下面咱們看些簡單用法,點擊後將當前流映射成新的流api
<template> <div> <h3>demo4 各類map方法運用</h3> <button class="btn" v-stream:click="getConcatMapCount$">點擊獲取concatMapCount$</button> <p>{{ concatMapCount$ }}</p> <button class="btn" v-stream:click="getSwitchMapCount$">點擊獲取switchMapCount$</button> <p>{{ switchMapCount$ }}</p> <button class="btn" v-stream:click="getExhaustMapCount$">點擊獲取exhaustMapCount$</button> <p>{{ exhaustMapCount$ }}</p> </div> </template> <script> import Rx from 'rxjs/Rx' export default { data () { return { count: 0 } }, domStreams: [ 'getConcatMapCount$', 'getSwitchMapCount$', 'getExhaustMapCount$' ], subscriptions () { /** * 下面的operator會把一個Observable轉化成另一個Observable * 經過返回一個觀察流繼續處理數據 */ return { /** * 當你連續點擊按鈕屢次獲取數據時,cancatMap會將獲取到的數據按隊列發出 */ concatMapCount$: this.getConcatMapCount$ .concatMap((e) => { return Rx.Observable.from(this.getCount()) }), /** * 當你連續點擊按鈕屢次獲取數據時,switchMap只會將最後一個點擊發出的值發出,前面發出的值會被吞掉 */ switchMapCount$: this.getSwitchMapCount$ .switchMap((e) => { return Rx.Observable.from(this.getCount()) }), /** * 當你連續點擊按鈕屢次時,exhaustMap僅執行一次,在第一次值發出後,才能夠繼續點擊下一次發出值 */ exhaustMapCount$: this.getExhaustMapCount$ .exhaustMap(e => { return Rx.Observable.from(this.getCount()) }) } }, methods: { getCount () { return new Promise((resolve, reject) => { this.count++ setTimeout(() => { resolve(this.count) }, 2000) }) } } } </script>
上面的getCount當成是2秒後響應的http請求,當你連續點擊的時候,這幾個map operator會有不同的行爲。
好比concatMap在屢次點擊後會每隔兩秒就發送一個遞增的count,而switchMap在屢次點擊後,會只發出最後一次點擊的count,好比我點了3次,switchMapCount$在2秒後會顯示3,而不是1,exhaustMap則是第一次點擊沒有響應前不會執行後續的點擊操做,直到響應後的點擊纔有效。
4、關於Rx5與Rx6 上面的倉庫是基於Rx5編寫的示例,而新出的Rx6在api上有些變更,調用operator的方式再也不是鏈式調用,而是經過傳入pipe operator進行組合使用,還有Observable對象的引用也發生了改變,具體能夠參考官方文檔
轉載於猿2048:➜《RxJS實踐,Vue如何集成RxJS》數組