Skip to content

Commit b6abbb3

Browse files
committed
redesign API
1 parent 14d1a96 commit b6abbb3

File tree

3 files changed

+113
-47
lines changed

3 files changed

+113
-47
lines changed

README.md

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,24 @@
22

33
Simple [RxJS](https://github.com/Reactive-Extensions/RxJS) binding for Vue.js.
44

5+
### Installation
6+
7+
- With global scripts: just make sure to include `vue-rx.js` after Vue.js and RxJS. It will be installed automatically.
8+
9+
- With NPM:
10+
11+
``` js
12+
var Vue = require('vue')
13+
var Rx = require('rx')
14+
var VueRx = require('vue-rx')
15+
16+
// tada!
17+
Vue.use(VueRx, Rx)
18+
19+
// The second argument is optional if you are not using RxJS but other generic observable implementations:
20+
Vue.use(VueRx)
21+
```
22+
523
### Usage
624

725
With NPM:
@@ -14,16 +32,56 @@ var VueRx = require('vue-rx')
1432
// tada!
1533
Vue.use(VueRx, Rx)
1634

17-
// now you can bind to Rx observables directly in `data`
35+
// provide Rx observables with the `subscriptions` option
1836
new Vue({
1937
el: '#app',
20-
data: {
38+
subscriptions: {
2139
msg: messageObservable
2240
}
2341
})
2442
```
2543

26-
With global scripts: just make sure to include `vue-rx.js` after Vue.js and RxJS. It will be installed automatically.
44+
``` html
45+
<!-- bind to it normally in templates -->
46+
<div>{{ msg }}</div>
47+
```
48+
49+
The `subscriptions` options can also take a function so that you can return unique observables for each component instance:
50+
51+
``` js
52+
Vue.component('foo', {
53+
subscriptions: function () {
54+
return {
55+
msg: Rx.Observable.create(...)
56+
}
57+
}
58+
})
59+
```
60+
61+
### Using with Alternative Observable Implementations
62+
63+
You can use this plugin with other observable implementations, as long as it implements the `.subscribe` and `.dispose / .unsubscribe` interface. For example, you can use it with `most.js` or Falcor streams.
64+
65+
### `$watchAsObservable`
66+
67+
> This feature requires using RxJS.
68+
69+
This is a prototype method added to instances. You can use it to create an observable from a value watcher:
70+
71+
``` js
72+
created:function () {
73+
this.$watchAsObservable('a')
74+
.subscribe(function (val) {
75+
console.log('stream value', val)
76+
},function (err) {
77+
console.error(err)
78+
},function () {
79+
console.log('complete')
80+
})
81+
}
82+
```
83+
84+
### Example
2785

2886
See `/example` for a simple example.
2987

example/example.html

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -60,22 +60,23 @@ <h1>{{ results.term }}</h1>
6060
var vm = new Vue({
6161
el: '#el',
6262
data: {
63-
a:5,
63+
a: 5
64+
},
65+
subscriptions: {
6466
results: dataSource
6567
}
66-
});
67-
68+
})
6869

6970
setTimeout(function () {
70-
vm.a = 17;
71-
},5000)
71+
vm.a = 17
72+
}, 5000)
7273

73-
vm.$watchAsObservable('a')
74-
.subscribe(function (val) {
75-
console.log('stream value',val);
76-
},function (err) {
77-
console.error(err)
78-
},function () {
79-
console.log('complete');
80-
})
74+
vm.$watchAsObservable('a')
75+
.subscribe(function (val) {
76+
console.log('stream value',val)
77+
},function (err) {
78+
console.error(err)
79+
},function () {
80+
console.log('complete')
81+
})
8182
</script>

vue-rx.js

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,36 @@
11
(function () {
22
function VueRx (Vue, Rx) {
3-
if (!Rx) {
4-
throw new Error(
5-
'vue-rx requires passing the Rx object to Vue.use() as the 2nd argument.'
6-
)
7-
}
3+
var warn = Vue.util.warn || function () {}
84

9-
var VueVersion = Number(Vue.version && Vue.version.split('.')[0])
10-
var initHook = VueVersion && VueVersion > 1 ? 'beforeCreate' : 'init'
5+
function defineReactive (vm, key, val) {
6+
if (key in vm) {
7+
vm[key] = val
8+
} else {
9+
Vue.util.defineReactive(vm, key, val)
10+
}
11+
}
1112

12-
var mixin = {
13+
Vue.mixin({
14+
created () {
15+
var vm = this
16+
var obs = vm.$options.subscriptions
17+
if (typeof obs === 'function') {
18+
obs = obs.call(vm)
19+
}
20+
if (!obs) return
21+
vm._rxHandles = []
22+
Object.keys(obs).forEach(function (key) {
23+
defineReactive(vm, key, undefined)
24+
var ob = obs[key]
25+
if (!ob || typeof ob.subscribe !== 'function') {
26+
warn('Invalid Observable found in rx option with key "' + key + '".', vm)
27+
return
28+
}
29+
vm._rxHandles.push(obs[key].subscribe(function (value) {
30+
vm[key] = value
31+
}))
32+
})
33+
},
1334
beforeDestroy: function () {
1435
if (this._rxHandles) {
1536
this._rxHandles.forEach(function (handle) {
@@ -21,32 +42,18 @@
2142
})
2243
}
2344
}
24-
}
45+
})
2546

26-
mixin[initHook] = function init () {
27-
var self = this
28-
var dataFn = this.$options.data
29-
if (dataFn) {
30-
this.$options.data = function () {
31-
var raw = dataFn()
32-
Object.keys(raw).forEach(function (key) {
33-
var val = raw[key]
34-
if (val && val.subscribe instanceof Function) {
35-
raw[key] = null
36-
;(self._rxHandles || (self._rxHandles = []))
37-
.push(val.subscribe(function (value) {
38-
self[key] = raw[key] = value
39-
}))
40-
}
41-
})
42-
return raw
43-
}
47+
Vue.prototype.$watchAsObservable = function (expOrFn, options) {
48+
if (!Rx) {
49+
warn(
50+
'$watchAsObservable requires passing the Rx to Vue.use() as the ' +
51+
'second argument.',
52+
this
53+
)
54+
return
4455
}
45-
}
46-
47-
Vue.mixin(mixin)
4856

49-
Vue.prototype.$watchAsObservable = function (expOrFn, options) {
5057
var self = this
5158

5259
var obs$ = Rx.Observable.create(function (observer) {

0 commit comments

Comments
 (0)