axios ialah klien HTTP ringan yang melaksanakan permintaan HTTP berdasarkan perkhidmatan XMLHttpRequest
Ia menyokong konfigurasi kaya, Promise, penyemak imbas dan bahagian Node. Sejak Vue2.0, Youda mengumumkan bahawa ia akan membatalkan pengesyoran rasmi vue-resource
dan sebaliknya mengesyorkan axios. Kini axios telah menjadi pilihan pertama bagi kebanyakan pembangun Vue. (Jika anda tidak biasa dengan axios, anda boleh melihat APInya di sini.) [Cadangan berkaitan: tutorial video vue.js]
Sebelum merangkum, mari kita lihat dahulu, tanpa enkapsulasi Dalam kes ini, rupa permintaan axios dalam projek sebenar.
mungkin kelihatan seperti ini:
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); });
Anda boleh melihat bahawa dalam kod ini, logik kod halaman hanya pada baris 15, blok besar di atas Permintaan kod konfigurasi dan sebahagian besar kod pengendalian ralat tindak balas di bawah hampir tiada kaitan dengan fungsi halaman, dan kandungan ini adalah serupa dalam setiap permintaan, malah sesetengah bahagian adalah sama.
1. Langkah-langkah Enkapsulasi
Intipati enkapsulasi ialah menambah pelbagai perkara di luar kandungan untuk dikapsulkan, dan kemudiannya meletakkannya Ia dipersembahkan kepada pengguna sebagai keseluruhan baharu untuk mencapai pengembangan dan kemudahan penggunaan.
Encapsulation axios
Apa yang anda perlu lakukan ialah mengkonfigurasi konfigurasi yang biasa kepada semua permintaan HTTP pada axios terlebih dahulu, simpan parameter dan antara muka yang diperlukan, dan kemudian mengembalikannya sebagai aksios baharu.
Struktur direktori adalah seperti berikut (dijana oleh Vue-cli 3.0):
2 Sasaran pakej|--public/
|--mock/
|. |--db.json # Data simulasi antara muka baharu saya
|--src/
| |--komponen/
|.
|. |--store/
|.--pandangan/
| |--Home.Vue
| |--App.vue
| >|. |--theme.styl
|--package.json
|...
dihidupkan Halaman utama , membuat permintaan axios adalah semudah memanggil kaedah dengan hanya beberapa parameter, jadi saya boleh fokus pada kod perniagaan.
1. Bungkus axios ke dalam fail berasinganBuat fail utils/http.js di bawah src
cd src mkdir utils touch http.js
// src/utils/http.js import axios from 'axios';
//src/utils/http.js //... class NewAxios { }
, supaya projek boleh menukar alamat hos permintaan secara automatik dalam persekitaran yang berbeza dengan hanya melaksanakan arahan pembungkusan yang sepadan. 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
// src/utils/http.js //... class NewAxios { constructor() { //... this.timeout = 10000; } }
widthCredentials
true
// src/utils/http.js //... class NewAxios { constructor() { //... this.withCredentials = true; } }
request
Anda juga boleh terus menggunakan tika aksios yang dieksport lalai tanpa menciptanya, dan kemudian meletakkan semua konfigurasi padanya, tetapi dengan cara ini keseluruhan projek akan berkongsi satu tika aksios. Walaupun ini mencukupi untuk kebanyakan projek, permintaan dan struktur tindak balas alamat perkhidmatan yang berbeza dalam sesetengah projek mungkin berbeza sama sekali. Dalam kes ini, perkongsian satu contoh tidak boleh menyokongnya. Jadi untuk menjadikan enkapsulasi lebih serba boleh dan fleksibel, saya akan menggunakan kaedah
supaya setiap permintaan adalah contoh aksios baharu. axios
create
// 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实例的执行结果 } }
Saya akan mengkonfigurasi satu di sini
.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)); } //... }
pemprosesan. Contohnya, menapis data tindak balas, dan yang lebih penting, pemprosesan ralat bersatu untuk pelbagai kod ralat respons, pemprosesan pemotongan rangkaian, dsb. then
catch
Saya akan menilai 403 dan memutuskan sambungan di sini.
// 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); }); } //... }
Paparkan pemuatan dalam pemintas permintaan dan keluarkan pemuatan dalam pemintas tindak balas. Dengan cara ini, semua permintaan akan mempunyai kesan bersatu. loading
// src/utils/http.js //... export default new NewAxios();
Sekarang
// src/utils/http.js import axios from 'axios'; 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); this.timeout = 10000; this.withCredentials = true; } // 这里的url可供你针对需要特殊处理的接口路径设置不同拦截器。 setInterceptors = (instance, url) => { instance.interceptors.request.use((config) => { // 在这里添加loading // 配置token config.headers.AuthorizationToken = localStorage.getItem('AuthorizationToken') || ''; return config; }, err => Promise.reject(err)); instance.interceptors.response.use((response) => { // 在这里移除loading // todo: 想根据业务需要,对响应结果预先处理的,都放在这里 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); }); } 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();
axios
在 api 目录下新建 index.js,把其他文件的接口都在这个文件里汇总导出。 这层封装将我们的新的axios封装到了更简洁更语义化的接口方法中。 现在我们的目录结构长这样: |--public/ 4.使用封装后的axios 现在我们要发HTTP请求时,只需引入 api 下的 index.js 文件就可以调用任何接口了,并且用的是封装后的 axios。 axios请求被封装在fetchData函数里,页面请求压根不需要出现任何axios API,悄无声息地发起请求获取响应,就像在调用一个简单的 Promise 函数一样轻松。并且在页面中只需专注处理业务功能,不用被其他事物干扰。 Atas ialah kandungan terperinci Menghuraikan permintaan enkapsulasi axios dalam vue (dengan kod langkah). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!home.js
。我们需要把接口根据一定规则分好类,一类接口对应一个js文件。这个分类可以是按页面来划分,或者按模块等等。为了演示更直观,我这里就按页面来划分了。实际根据自己的需求来定。// src/api/home.js
import axios from '@/utils/http';
export const fetchData = options => axios.request({
...options,
url: '/data',
});
export default {};
// src/api/index.js
export * from './home';
|--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
|...// 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 '@/api/index';
export default {
name: 'home',
mounted() {
fetchData() // axios请求在这里
.then((data) => {
console.log(data);
})
.catch((err) => {
console.log(err);
});
},
};
</script>