zl程序教程

您现在的位置是:首页 >  前端

当前栏目

[Vue-rx] Pass Template Data Through domStreams in Vue.js and RxJS

VueJS in and Data Template Rxjs pass
2023-09-14 09:00:50 时间

domStreams enable you to pass additional data along the stream that can be provided by the template (such as data coming from a v-forrendering of an Array). You can then pluck off the data from the stream and use it further down the stream.

 

<template>
  <section class="section">
    <button class="button" :disabled="disabled$" v-stream:click="{subject: click$, data: 1}">{{buttonText$}}</button>
    <h2>
      {{name$}}
    </h2>
    <img v-stream:error="imageError$" :src="image$" alt="">
  </section>
</template>

<script>
import { from, of, merge, throwError } from 'rxjs';
import {
  exhaustMap,
  switchMap,
  pluck,
  map,
  mapTo,
  catchError,
  shareReplay,
  share,
  startWith
} from 'rxjs/operators';

export default {
  name: 'app',
  domStreams: ['click$', 'imageError$'],
  subscriptions() {
    const createLoader = url => from(this.$http.get(url)).pipe(pluck('data'));

    const luke$ = this.click$.pipe(
      pluck('data'),
      map(id => `https://starwars.egghead.training/people/${id}`),
      exhaustMap(createLoader),
      catchError(() => of({name: 'Failed.. :('})),
      share()
    );

    const name$ = luke$.pipe(pluck('name'));

    const loadImage$ = luke$.pipe(
      pluck('image'),
      map(src => `https://starwars.egghead.training/${src}`)
    );

    const failImage$ = this.imageError$.pipe(
      mapTo(`http://via.placeholder.com/400x400`)
    );

    const image$ = merge(
      loadImage$,
      failImage$
    )

    const disabled$ = merge(
      this.click$.pipe(mapTo(true)),
      luke$.pipe(mapTo(false)),
    ).pipe(startWith(false));

    const buttonText$ = disabled$.pipe(map(b => (b ? 'Loading...' : 'Load')));


    return {
      name$,
      image$,
      failImage$,
      disabled$,
      buttonText$
    };
  }
};
</script>