Skip to content

Instantly share code, notes, and snippets.

@Brooooooklyn
Created October 11, 2016 06:14
Show Gist options
  • Save Brooooooklyn/ae59eab6a49c0f5460f0a1572e8f63ba to your computer and use it in GitHub Desktop.
Save Brooooooklyn/ae59eab6a49c0f5460f0a1572e8f63ba to your computer and use it in GitHub Desktop.
RxJS 5.0.0 mixin for Vuejs 1.x
import { Observable } from 'rxjs/Observable'
import { Subscription } from 'rxjs/Subscription'
/**
* @see https://github.com/vuejs/vue-rx
*/
let isInstalled = false
export function VueRx(Vue) {
if (isInstalled) {
return
}
isInstalled = true
Vue.mixin({
ready() {
// 期望如下执行次序
// ... -> ready() -> vm.ready() -> $nextTick()
// 保证`vm`已完全初始化
this.$nextTick(() => {
const originData = this.$data
const newData = {}
const cacheData = {}
if (!this._rx$) {
this._rx$ = new Map<string, Subscription>()
}
const __this = this
Object.keys(originData).forEach(key => {
newData[key] = null
const $ = this[key]
if ($ instanceof Observable) {
cacheData[key] = originData[key]
Object.defineProperty(originData, key, {
get() {
return cacheData[key]
},
set(value: any) {
if (__this._rx$.has(key)) {
__this._rx$.get(key).unsubscribe()
}
if (value instanceof Observable) {
__this._rx$.set(key, value.subscribe(r => {
newData[key] = r
}))
} else {
newData[key] = value
}
cacheData[key] = value
}
})
this._rx$.set(key,
$.subscribe(value => {
newData[key] = value
})
)
} else {
cacheData[key] = $
Object.defineProperty(newData, key, {
set(this: any, val: any) {
cacheData[key] = val
},
get(this: any) {
return cacheData[key]
}
})
Object.defineProperty(originData, key, {
set (this: any, value: any) {
newData[key] = value
},
get (this: any) {
return newData[key]
}
})
}
})
this.$data = newData
this.data$ = originData
})
},
beforeDestroy() {
if (this._rx$) {
this._rx$.forEach((subscription: Subscription) => {
subscription.unsubscribe()
})
}
}
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment