點燈坊

失くすものさえない今が強くなるチャンスよ

RxJS 初體驗

Sam Xiao's Avatar 2020-06-10

若說 Ramda 是 FP 對於 Synchronous 解決方案,RxJS 則是 FP 在 ECMAScript 對於 Asynchronous 解決方案。Vue 官方已經將 RxJS 整合進 Vue,稱為 Vue-rx。

Version

macOS Catalina 10.15.4
WebStorm 2020.1
Vue 2.6.11
Vue-rx 6.2
RxJS 6.5.5

安裝 Vue-rx

$  yarn add vue-rx rxjs

雖然 Vue-rx 是 Vue 官方所維護,但目前 Vue-rx 並不像 Vuex 可透過 Vue CLI 安裝,必須自行使用 Yarn。

vue-rx000

vue-rx001

安裝完會發現在專案根目錄的 package.json 多了 rxjsvue-rx

Main.js

main.js

import Vue from 'vue'
import VueRx from 'vue-rx'
import App from './App.vue'

Vue.use(VueRx)
Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

第 2 行

import VueRx from 'vue-rx'

Import vue-rx

第 5 行

Vue.use(VueRx)

讓 Vue instance 可以使用 VueRx

Component

<template>
  <div>
    <h1>{{ interval$ }}</h1>
  </div>
</template>

<script>
import { interval } from 'rxjs'

let subscriptions = _ => {
  let interval$ = interval(1000)

  return { interval$ }
}

export default {
  name: 'app',
  subscriptions,
}
</script>

首先來看最簡單的 Vue-rx 應用。

第 8 行

import { interval } from 'rxjs'

先 import RxJS 的 interval()

10 行

let subscriptions = _ => {
  let interval$ = interval(1000)

  return { interval$ }
}

Vue-rx 提供了 subscriptions,專門處理 RxJS 的 Observable。

其中 subscriptions 如同 datacomputed 一樣都是 function,回傳的是 Object。

Observable 建議的命名方式是在名稱後面加上 $interval() 每 1 秒鐘會送出新的值,依序遞增。

第 1 行

<template>
  <h1>{{ interval$ }}</h1>
</template>

在 HTML template 可直接使用在 subscriptions 定義的 $interval$ Observable。

vue-rx002

執行後會發現 interval$ 不斷地遞增。

RxJS

<template>
  <div>
    <h1>{{ interval }}</h1>
  </div>
</template>

<script>
import { interval } from 'rxjs'

let mounted = function() {
  interval(1000)
    .subscribe(x => this.interval = x)
}

export default {
  name: 'app',
  data: () => ({
    interval
  }),
  mounted
}
</script>

Q:一定得使用 Vue-rx 才能使用 RxJs 嗎 ? 可使用原生的 RxJS 嗎 ?

17 行

data: () => ({
  interval
}),

宣告 interval data,因為不是 Observable,因此 postfix 不用加上 $

10 行

let mounted = function() {
  interval(1000)
    .subscribe(x => this.interval = x)
}

subscribe() 寫入 interval side effect,因為需要 this 所以寫在 mounted hook 內。

Conclusion

  • 這就是最簡單的 Vue + Vue-rx,重點先將環境裝好,日後才能練習更進階應用
  • 就算沒有 Vue-rx,我們也能使用原生 RxJS,只要在 subscribe() 寫入 side effect 即可

Reference

John Lindquist, Configure Vue.js to Enable RxJS Streams
Vue, vuejs/vue-rx
RxJS, ReactiveX/rxjs