Vue 中的进度条服务

Service for progress bar in Vue

在Angular我一般有一个专门的class是负责进度条的。我可以像这样拦截所有 HTTP 请求和路由请求,它甚至适用于 GraphQL 请求:

加载指示器服务

import { Injectable } from '@angular/core';
import { Router, NavigationStart, NavigationCancel, NavigationEnd, NavigationError } from '@angular/router';
import { Subject, BehaviorSubject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class LoadingIndicatorService {

  loading: BehaviorSubject<boolean> = new BehaviorSubject(false);

  constructor(private router: Router) {
    this.router.events.subscribe((event) => {

      switch (true) {
        case event instanceof NavigationStart: {
          this.show();
          break;
        }
        case event instanceof NavigationEnd:
        case event instanceof NavigationCancel:
        case event instanceof NavigationError: {

          this.hide();
          break;
        }


        default:
          break;
      }

    });
  }

  show() {
    this.loading.next(true);
  }

  hide() {
    this.loading.next(false);
  }
}

加载拦截器服务

import { Injectable } from '@angular/core';
import { LoadingIndicatorService } from './loading-indicator.service';
import {
  HttpErrorResponse,
  HttpResponse,
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { finalize } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class LoadingInterceptorService implements HttpInterceptor {

  constructor(private loadingService: LoadingIndicatorService) { }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    this.loadingService.show();

    return next.handle(req)
      .pipe(
        finalize(() => this.loadingService.hide())
      );

  }
}

是否可以像 Angular 那样在 Vue 中全局拦截 HTTP GraphQL 请求,所以一个地方和一个 class 负责此功能?因为现在,我需要为每个组件中的每个请求检查 loading,并且在每个组件中控制进度条。

这就是我现在尝试这样做的方式,但显然这种方式行不通。我认为 $apollo 是一个全局变量,它控制来自所有组件的所有查询

进度-bar.vue

<template>
  <div class="progress-bar-component" v-if="$apollo.loading">
    <div class="bar">{{this.$apollo.loading}}</div>
  </div>
</template>

<script>
export default {
  apollo: {}
};
</script>

<style>
.bar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  /* height: 5px; */
  color: white;
  background-color: brown;
}
</style>

提前致谢!

设置您的 VueApollo 实例时,您可以传递一个 watchLoading 挂钩来监视所有查询:

const apolloProvider = new VueApollo({
  watchLoading (isLoading, countModifier) {
    loading += countModifier
    console.log('Global loading', loading, countModifier)
  },
  //...
})

属性 记录在 Smart Query options:

watchLoading(isLoading, countModifier) is a hook called when the loading state of the query changes. The countModifier parameter is either equal to 1 when the query is loading, or -1 when the query is no longer loading.