axios のカプセル化リクエストを vue で解析します (ステップコード付き)

藏色散人
リリース: 2022-08-10 10:05:54
転載
1768 人が閲覧しました

1. はじめに

axios は、XMLHttpRequest サービスに基づいて HTTP リクエストを実行し、豊富な構成をサポートし、Promise をサポートし、サーバー側のブラウジングをサポートする軽量の HTTP クライアントです。 Node.js側。 Vue2.0 以降、Youda は vue-resource の公式推奨を中止し、代わりに axios を推奨すると発表しました。現在、axios はほとんどの Vue 開発者にとって最初の選択肢となっています。 (axios に詳しくない場合は、ここでその API を参照できます。) [関連する推奨事項: vue.js ビデオ チュートリアル ]

カプセル化する前に、まず見てみましょう。カプセル化なし この場合、axios リクエストは実際のプロジェクトでどのように見えるか。

おそらく次のようになります:

axios('http://localhost:3000/data', {
  method: 'GET',
  timeout: 1000,
  withCredentials: true,
  headers: {
    'Content-Type': 'application/json',
    Authorization: 'xxx',
  },
  transformRequest: [function (data, headers) {
    return data;
  }],
  // 其他请求配置...
})
.then((data) => {
  // todo: 真正业务逻辑代码
  console.log(data);
}, (err) => {
  if (err.response.status === 401) {
  // handle authorization error
  }
  if (err.response.status === 403) {
  // handle server forbidden error
  }
  // 其他错误处理.....
  console.log(err);
});
ログイン後にコピー

このコードでは、ページ コード ロジックは 15 行目にのみあり、リクエスト構成の大きなブロックがあることがわかります。上記のコードおよび以下の応答エラー処理コードの大部分は、ページ関数とはほとんど関係がありません。これらの内容はどのリクエストでも類似しており、一部の部分はまったく同じです。

2. カプセル化後

#1. カプセル化の手順

カプセル化の本質は、カプセル化するコンテンツの外側にさまざまなものを追加し、拡張性と使いやすさを実現するために、新しい全体としてユーザーに提示されます。

カプセル化

axios すべての HTTP リクエストに共通の設定を axios 上で事前に設定し、必要なパラメータとインターフェイスを予約し、それを新しい axios として使用する必要があります。戻り値。

##ディレクトリ構造は次のとおりです (Vue-cli 3.0 によって生成):

|--public/

|--mock/
| |--db.json # 新しいインターフェイス シミュレーション データ

|--src/
| |--assets/
| |--components/
| |--router/
| |--store/
| |--views/
| |--Home.Vue
| |--App.vue
| |--main.js
| |--theme.styl
|--package.json
|...


2. のパッケージ ターゲット

ホームページ 、axios リクエストの作成は、いくつかのパラメーターのみを使用してメソッドを呼び出すだけなので簡単なので、ビジネス コードに集中できます。

1. axios を別のファイルにカプセル化します

src

      cd src
      mkdir utils
      touch http.js
    ログイン後にコピー
  • # の下に utils/http.js ファイルを作成します##axios の紹介
  // src/utils/http.js
  import axios from 'axios';
ログイン後にコピー
    #クラスを作成する
  • ##
      //src/utils/http.js
      //...
      class NewAxios {
      
      }
    ログイン後にコピー
  • #環境ごとに異なるリクエスト アドレスを構成する
    Configure
  • process.env.NODE_ENV
  • に従って異なる
baseURL
    を使用するため、プロジェクトは対応するパッケージング コマンドを実行するだけで、異なる環境でリクエスト ホスト アドレスを自動的に切り替えることができます。
  • // src/utils/http.js
    
    //...
    const getBaseUrl = (env) => {
      let base = {
        production: '/',
        development: 'http://localhost:3000',
        test: 'http://localhost:3001',
      }[env];
      if (!base) {
        base = '/';
      }
      return base;
    };
    
    class NewAxios {
      constructor() {
        this.baseURL = getBaseUrl(process.env.NODE_ENV);
      }
    }
    ログイン後にコピー
timeout

timeout 属性の構成。通常は 10 秒に設定します。

// src/utils/http.js

//...
class NewAxios {
  constructor() {
    //...
    this.timeout = 10000;
  }
}
ログイン後にコピー
  • 資格情報の保持を許可する構成

widthCredentials プロパティが

true
  • // src/utils/http.js
    
    //...
    class NewAxios {
      constructor() {
        //...
        this.withCredentials = true;
      }
    }
    ログイン後にコピー
  • # に設定されています## このクラスのインスタンスにメソッド request

を作成します。request メソッドで、新しい axios インスタンスを作成し、リクエスト構成パラメーターを受け取り、パラメーターを処理し、追加します。構成を取得し、axios インスタンスのリクエスト結果 (Promise オブジェクト) を返します。

エクスポートされたデフォルトの axios インスタンスを作成せずに直接使用し、そこにすべての設定を配置することもできます。ただし、この方法では、プロジェクト全体が 1 つの axios インスタンスを共有することになります。ほとんどのプロジェクトではこれで十分ですが、プロジェクトによっては、異なるサービス アドレスのリクエストとレスポンスの構造が完全に異なる場合があり、この場合、1 つのインスタンスの共有ではサポートできません。したがって、カプセル化をより多用途かつ柔軟にするために、
    axios
  • create
メソッドを使用して、各リクエストが新しい axios インスタンスになるようにします。

// src/utils/http.js

//...
class NewAxios {
  //...
  request(options) {
    // 每次请求都会创建新的axios实例。
    const instance = axios.create();
    const config = { // 将用户传过来的参数与公共配置合并。
      ...options,
      baseURL: this.baseURL,
      timeout: this.timeout,
      withCredentials: this.withCredentials,
    };
    // 配置拦截器,支持根据不同url配置不同的拦截器。
    this.setInterceptors(instance, options.url);
    return instance(config); // 返回axios实例的执行结果
  }
}
ログイン後にコピー
インターセプタ設定の内容は比較的大きいため、内部関数にカプセル化されます。

リクエスト インターセプタの設定リクエストを送信する前のリクエスト パラメータに対するすべての変更は、ここで設定されます。たとえば、トークン資格情報を均一に追加し、言語を均一に設定し、コンテンツ タイプを均一に設定し、データ形式を指定します。終了後に必ずこの構成を返してください。そうしないと、リクエスト全体が続行されません。

ここで

token

を構成します。
    // src/utils/http.js
    
    //...
    class NewAxios {
      //...
      // 这里的url可供你针对需要特殊处理的接口路径设置不同拦截器。
      setInterceptors = (instance, url) => { 
        instance.interceptors.request.use((config) => { // 请求拦截器
          // 配置token
          config.headers.AuthorizationToken = localStorage.getItem('AuthorizationToken') || '';
          return config;
        }, err => Promise.reject(err));
      }
      //...
    }
    ログイン後にコピー
  • 応答インターセプターの構成

リクエストの

then または catch# の前に応答データの前処理を実行します。 ## 処理を処理します。たとえば、応答データのフィルタリング、さらに重要なことに、さまざまな応答エラー コードに対する統合エラー処理、ネットワーク切断処理などが挙げられます。

    403と切断についてはここで判断させていただきます。
  • // src/utils/http.js
    
    //...
    class NewAxios {
      //...
      setInterceptors = (instance, url) => {
        //...
        instance.interceptors.response.use((response) => { // 响应拦截器
          // todo: 想根据业务需要,对响应结果预先处理的,都放在这里
          console.log();
          return response;
        }, (err) => {
          if (err.response) { // 响应错误码处理
            switch (err.response.status) {
              case '403':
                // todo: handler server forbidden error
                break;
                // todo: handler other status code
              default:
                break;
            }
            return Promise.reject(err.response);
          }
          if (!window.navigator.online) { // 断网处理
            // todo: jump to offline page
            return -1;
          }
          return Promise.reject(err);
        });
      }
      //...
    }
    ログイン後にコピー
さらに、インターセプターでは、ローディングなどのバッファリング効果を配置することも適しています。

リクエスト インターセプターでローディングを表示し、レスポンス インターセプターでローディングを削除します。このようにして、すべてのリクエストに統一された loading 効果が適用されます。

デフォルトで新しいインスタンスをエクスポート

  // src/utils/http.js
  
  //...
  export default new NewAxios();
ログイン後にコピー

最終的な完全なコードは次のとおりです: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:bash;">// src/utils/http.js import axios from &amp;#39;axios&amp;#39;; const getBaseUrl = (env) =&gt; { let base = { production: &amp;#39;/&amp;#39;, development: &amp;#39;http://localhost:3000&amp;#39;, test: &amp;#39;http://localhost:3001&amp;#39;, }[env]; if (!base) { base = &amp;#39;/&amp;#39;; } return base; }; class NewAxios { constructor() { this.baseURL = getBaseUrl(process.env.NODE_ENV); this.timeout = 10000; this.withCredentials = true; } // 这里的url可供你针对需要特殊处理的接口路径设置不同拦截器。 setInterceptors = (instance, url) =&gt; { instance.interceptors.request.use((config) =&gt; { // 在这里添加loading // 配置token config.headers.AuthorizationToken = localStorage.getItem(&amp;#39;AuthorizationToken&amp;#39;) || &amp;#39;&amp;#39;; return config; }, err =&gt; Promise.reject(err)); instance.interceptors.response.use((response) =&gt; { // 在这里移除loading // todo: 想根据业务需要,对响应结果预先处理的,都放在这里 return response; }, (err) =&gt; { if (err.response) { // 响应错误码处理 switch (err.response.status) { case &amp;#39;403&amp;#39;: // todo: handler server forbidden error break; // todo: handler other status code default: break; } return Promise.reject(err.response); } if (!window.navigator.online) { // 断网处理 // todo: jump to offline page return -1; } return Promise.reject(err); }); } request(options) { // 每次请求都会创建新的axios实例。 const instance = axios.create(); const config = { // 将用户传过来的参数与公共配置合并。 ...options, baseURL: this.baseURL, timeout: this.timeout, withCredentials: this.withCredentials, }; // 配置拦截器,支持根据不同url配置不同的拦截器。 this.setInterceptors(instance, options.url); return instance(config); // 返回axios实例的执行结果 } } export default new NewAxios();</pre><div class="contentsignin">ログイン後にコピー</div></div>Now

axios
    カプセル化は 80% 完了しました。最初に設定したカプセル化の目標を達成するには、axios とインターフェイスをさらに結合し、さらに 1 層カプセル化する必要があります。
3. 新しい axios パッケージング API

を使用する

  • 在 src 目录下新建 api 文件夹。把所有涉及HTTP请求的接口统一集中到这个目录来管理。
  • 新建 home.js。我们需要把接口根据一定规则分好类,一类接口对应一个js文件。这个分类可以是按页面来划分,或者按模块等等。为了演示更直观,我这里就按页面来划分了。实际根据自己的需求来定。
  • 使用新的 axios 封装API(固定url的值,合并用户传过来的参数),然后命名导出这些函数。
// src/api/home.js 

import axios from &#39;@/utils/http&#39;;
export const fetchData = options => axios.request({
  ...options,
  url: &#39;/data&#39;,
});
export default {};
ログイン後にコピー

在 api 目录下新建 index.js,把其他文件的接口都在这个文件里汇总导出。

 // src/api/index.js
  
  export * from &#39;./home&#39;;
ログイン後にコピー

这层封装将我们的新的axios封装到了更简洁更语义化的接口方法中。

现在我们的目录结构长这样:

|--public/
|--mock/
| |--db.json # 接口模拟数据
|--src/
| |--api/ # 所有的接口都集中在这个目录下
| |--home.js # Home页面里涉及到的接口封装在这里
| |--index.js # 项目中所有接口调用的入口
| |--assets/
| |--components/
| |--router/
| |--store/
| |--utils/
| |--http.js # axios封装在这里
| |--views/
| |--Home.Vue
| |--App.vue
| |--main.js
| |--theme.styl
|--package.json
|...

4.使用封装后的axios

现在我们要发HTTP请求时,只需引入 api 下的 index.js 文件就可以调用任何接口了,并且用的是封装后的 axios。

// src/views/Home.vue

<template>
  <div class="home">
    <h1>This is home page</h1>
  </div>
</template>

<script>
// @ is an alias to /src
import { fetchData } from &#39;@/api/index&#39;;

export default {
  name: &#39;home&#39;,
  mounted() {
    fetchData()  // axios请求在这里
      .then((data) => {
        console.log(data);
      })
      .catch((err) => {
        console.log(err);
      });
  },
};
</script>
ログイン後にコピー

axios请求被封装在fetchData函数里,页面请求压根不需要出现任何axios API,悄无声息地发起请求获取响应,就像在调用一个简单的 Promise 函数一样轻松。并且在页面中只需专注处理业务功能,不用被其他事物干扰。

以上がaxios のカプセル化リクエストを vue で解析します (ステップコード付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:jb51.net
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート