Skip to content
This repository was archived by the owner on Oct 28, 2022. It is now read-only.

Commit ef94798

Browse files
author
NOPR9D
committed
feat: create observable method | mixins
1 parent 5984d70 commit ef94798

File tree

7 files changed

+188
-13
lines changed

7 files changed

+188
-13
lines changed

README.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,47 @@ const vm = new Vue({
270270
271271
---
272272
273+
## `$createObservableMethod(methodName)`
274+
275+
Convert function calls to observable sequence which emits the call arguments.
276+
277+
This is a prototype method added to instances. Use it to create a shared hot observable from a function name. The function will be assigned as a vm method.
278+
279+
```html
280+
<custom-form :onSubmit="submitHandler"></custom-form>
281+
```
282+
283+
```js
284+
const vm = new Vue({
285+
subscriptions() {
286+
return {
287+
// requires `share` operator
288+
formData: this.$createObservableMethod("submitHandler"),
289+
};
290+
},
291+
});
292+
```
293+
294+
You can use the `observableMethods` option to make it more declarative:
295+
296+
```js
297+
new Vue({
298+
observableMethods: {
299+
submitHandler: "submitHandler$",
300+
// or with Array shothand: ['submitHandler']
301+
},
302+
});
303+
```
304+
305+
The above will automatically create two things on the instance:
306+
307+
1. A `submitHandler` method which can be bound to in template with `v-on`;
308+
2. A `submitHandler$` observable which will be the stream emitting calls to `submitHandler`.
309+
310+
[example](https://github.com/vuejs/vue-rx/blob/master/example/counter-function.html)
311+
312+
---
313+
273314
## Example
274315
275316
See `/examples` for some simple examples.
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<!-- this demo requires a browser that natively supports ES2015 -->
2+
3+
<script src="https://unpkg.com/rxjs/bundles/rxjs.umd.js"></script>
4+
<script src="https://unpkg.com/vue@next"></script>
5+
<script src="../dist/vue-next-rx.js"></script>
6+
<div id="app">
7+
<div>{{ count }}</div>
8+
9+
<!-- callback declared on observableMethods -->
10+
<button v-on:click="muchMore(500)">Add 500</button>
11+
12+
<button v-on:click="minus(minusDelta1)">Minus on Click</button>
13+
14+
<pre>{{ $data }}</pre>
15+
</div>
16+
<script>
17+
const { merge } = rxjs;
18+
const { startWith, scan } = rxjs.operators;
19+
const { ref, watch } = VueNextRx;
20+
21+
const app = Vue.createApp({
22+
observableMethods: {
23+
muchMore: "muchMore$",
24+
minus: "minus$",
25+
},
26+
data() {
27+
return {
28+
minusDelta1: -1,
29+
minusDelta2: -1,
30+
};
31+
},
32+
subscriptions() {
33+
return {
34+
count: merge(this.muchMore$, this.minus$).pipe(
35+
startWith(0),
36+
scan((total, change) => total + change)
37+
),
38+
};
39+
},
40+
}).use(VueNextRx);
41+
app.mount("#app");
42+
</script>

package-lock.json

Lines changed: 9 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@nopr3d/vue-next-rx",
3-
"version": "1.0.4",
3+
"version": "1.0.5",
44
"description": "RxJs for Vue 3",
55
"author": "Boucham Amine",
66
"license": "MIT",

rollup.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ module.exports = [
3333
globals: {
3434
vue: "Vue",
3535
rxjs: "rxjs",
36-
"rxjs/operators": "rxjs/ operators",
36+
"rxjs/operators": "rxjs.operators",
3737
},
3838
},
3939
plugins: [

src/mixin.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,19 @@ export default {
77
const domStreams = vm.$options.domStreams;
88

99
if (domStreams) {
10-
domStreams.forEach((key) => {
10+
domStreams.forEach(key => {
1111
vm[key] = new Subject();
1212
});
1313
}
1414

1515
const observableMethods = vm.$options.observableMethods;
1616
if (observableMethods) {
1717
if (Array.isArray(observableMethods)) {
18-
observableMethods.forEach((methodName) => {
18+
observableMethods.forEach(methodName => {
1919
vm[methodName + "$"] = vm.$createObservableMethod(methodName);
2020
});
2121
} else {
22-
Object.keys(observableMethods).forEach((methodName) => {
22+
Object.keys(observableMethods).forEach(methodName => {
2323
vm[observableMethods[methodName]] = vm.$createObservableMethod(
2424
methodName
2525
);
@@ -34,7 +34,7 @@ export default {
3434
if (obs) {
3535
vm.$observables = {};
3636
vm._subscription = new Subscription();
37-
Object.keys(obs).forEach((key) => {
37+
Object.keys(obs).forEach(key => {
3838
vm[key] = undefined;
3939
const ob = (vm.$observables[key] = obs[key]);
4040
if (!isObservable(ob)) {
@@ -48,11 +48,11 @@ export default {
4848
}
4949
vm._subscription.add(
5050
obs[key].subscribe(
51-
(value) => {
51+
value => {
5252
vm[key] = value;
5353
this.$forceUpdate();
5454
},
55-
(error) => {
55+
error => {
5656
throw error;
5757
}
5858
)
@@ -65,5 +65,5 @@ export default {
6565
if (this._subscription) {
6666
this._subscription.unsubscribe();
6767
}
68-
},
68+
}
6969
};

test/test.js

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,3 +325,90 @@ test("$subscribeTo()", () => {
325325
next(2);
326326
expect(results).toEqual([1]); // should not trigger anymore
327327
});
328+
329+
test("$createObservableMethod() with no context", (done) => {
330+
const { ob, next } = mock();
331+
const results = [];
332+
const component = {
333+
template: defaultTemplate,
334+
created() {
335+
this.$createObservableMethod("add").subscribe(function (param) {
336+
expect(param).toEqual("hola");
337+
done();
338+
});
339+
},
340+
};
341+
342+
const wrapper = mount(component);
343+
344+
wrapper.componentVM.$nextTick(() => {
345+
wrapper.componentVM.add("hola");
346+
});
347+
});
348+
349+
test("$createObservableMethod() with multi params & context", (done) => {
350+
const { ob, next } = mock();
351+
const results = [];
352+
var wrapper = { e: "" };
353+
const component = {
354+
template: defaultTemplate,
355+
created() {
356+
this.$createObservableMethod("add", true).subscribe(function (param) {
357+
expect(param[0]).toEqual("hola");
358+
expect(param[1]).toEqual("mundo");
359+
expect(param[2]).toEqual(wrapper.componentVM);
360+
done();
361+
});
362+
},
363+
};
364+
365+
wrapper = mount(component);
366+
367+
wrapper.componentVM.$nextTick(() => {
368+
wrapper.componentVM.add("hola", "mundo");
369+
});
370+
});
371+
372+
test("observableMethods mixin", (done) => {
373+
const { ob, next } = mock();
374+
const results = [];
375+
const component = {
376+
template: defaultTemplate,
377+
observableMethods: ["add"],
378+
created() {
379+
this.add$.subscribe(function (param) {
380+
expect(param[0]).toEqual("Qué");
381+
expect(param[1]).toEqual("tal");
382+
done();
383+
});
384+
},
385+
};
386+
387+
const wrapper = mount(component);
388+
389+
wrapper.componentVM.$nextTick(() => {
390+
wrapper.componentVM.add("Qué", "tal");
391+
});
392+
});
393+
394+
test("observableMethods mixin", (done) => {
395+
const { ob, next } = mock();
396+
const results = [];
397+
const component = {
398+
template: defaultTemplate,
399+
observableMethods: { add: "plus$" },
400+
created() {
401+
this.plus$.subscribe(function (param) {
402+
expect(param[0]).toEqual("Qué");
403+
expect(param[1]).toEqual("tal");
404+
done();
405+
});
406+
},
407+
};
408+
409+
const wrapper = mount(component);
410+
411+
wrapper.componentVM.$nextTick(() => {
412+
wrapper.componentVM.add("Qué", "tal");
413+
});
414+
});

0 commit comments

Comments
 (0)