專案中封裝axios

陸霸天發表於2018-10-29

made a plug named 'Fecth', first

follwing is the Fetch.js

import axios from 'axios'
const CancelToken = axios.CancelToken //the preparations for canling request actions
const source = CancelToken.source()

export default class Fetch {
    constructor (config) {
    	this.config = config
    	this.fetch = axios.create(config)
    	this.initIntercept()
    }
    
    get () {
    	let config = this.constructArgs(['GET', ...arguments])
    	return this.fetch(config)
    }
    
    post () {
    	let config = this.constructArgs(['POST', ...arguments])
    	return this.fetch(config)
    }
    
    // Vue注入
    install (Vue) {
    	Vue.prototype.$get = this.get.bind(this)
    	Vue.prototype.$post = this.post.bind(this)
    	Vue.prototype.$fetch = this.fetch.bind(this)
    	Vue.prototype.$fetchInstance = this
    }
    
    // 取消請求
    cancel (message) {
    	return source.cancel(message)
    }
    
    // 判斷請求錯誤是否是取消
    isCancel (err) {
    	return axios.isCancel(err)
    }
    
    // 構建引數
    constructArgs (args) {
    	let config = {
    		method: args[0]
    	}
    	// 引數 get('/api/get', data, options)
    	if (toString.call([],args[1]) === '[Object, String]') {
    		config.url = args[1]
    		config = {...config, ...args[3]}
    
    		if (config.method === 'GET') {
    			config.params = args[2]
    		} else {
    			config.data = args[2]
    		}
    	// 引數 get({url: '/api/get', data, options})
    	} else {
    		let customeConfig = args[1] || {}
    		config.url = customeConfig.url
    
    		if (config.method === 'GET') {
    			config.params = customeConfig.data
    		} else {
    			config.data = customeConfig.data
    		}
    		config = {...config, ...customeConfig.options}
    	}
    
    	config.cancelToken = source.token
    
    	return config
    }
    
    // 初始化攔截器
    initIntercept () {
    	/**
    	 * 請求攔截器
    	 * 可作用請求前修改請求配置
    	 * error 函式可全域性處理請求錯誤
    	 */
    	this.fetch.interceptors.request.use(
    		config => {
    			if (this.config.beforeRequest) {
    				const conf = this.config.beforeRequest(config, this.config)
    				return conf || config
    			} else {
    				return config
    			}
    		},
    		error => {
    			if (this.config.requestError) {
    				const err = this.config.requestError(error, this.config)
    				return err || Promise.reject(error)
    			} else {
    				return Promise.reject(error)
    			}
    		}
    	)
    
    	/**
    	 * 返回攔截器
    	 * 全域性處理返回資料驗證和資料構造
    	 * error 全域性處理錯誤問題
    	 */
    	this.fetch.interceptors.response.use(
    		response => {
    			if (this.config.beforeResponse) {
    				return this.config.beforeResponse(response, this.config)
    			} else {
    				return response
    			}
    		},
    		error => {
    			if (this.config.responseError) {
    				const err = this.config.responseError(error, this.config)
    				return err || Promise.reject(error)
    			} else {
    				return Promise.reject(error)
    			}
    		}
    	)
	}
}


複製程式碼

use plug nameed 'Fetcht', next

import Vue from 'vue'
import { Spin, Message } from 'iview'
import Fetch from './fetch.js'
<!--import { isMocked } from '~/plugins/mock'-->
var fetch = new Fetch({
    beforeRequest (config) {
    	let mockRequest = isMocked(config)
    	if (!mockRequest) {
    		config.url = '/merchant-admin-web/api' + config.url
    	}
    	if (localStorage.mock && mockRequest) {
    		let log = [
    			`%c Mock請求 %c${config.url}`,
    			'color:#FFFFFF;background:#55BB7B',
    			'text-decoration: underline'
    		]
    		console.log(...log)
    	}
    	let token = localStorage.token
    	// let token = localStorage.getItem('maw-token')
    	if (token) {
    		config.headers.token = token
    	}
    	if (!config.quite) Spin.show()
    	return config
    },
    beforeResponse ({data, config}) {
    	if (!config.quite) Spin.hide()
    	if (data.resultCode !== '000000') {
    	
    	} else {
    		if (data.token) {
    			localStorage.setItem('token', data.token)
    		}
    		return data.data
    	}
    },
    responseError ({error, config}) {
    	if (!config.quite) Spin.hide()
    	Message.error(error || '請求出錯')
    	return Promise.reject(error)
    }
})

Vue.use(fetch)

export const $get = function () {
	return fetch.get(...arguments)
}
export const $post = function () {
	return fetch.post(...arguments)
}
export const $fetch = function () {
	return fetch(...arguments)
}


複製程式碼

the end

now ,you must can made axios plugs by yourself!

by the way, let us see the the source code in the Vue

import { toArray } from '../util/index'

export function initUse (Vue: GlobalAPI) {
  Vue.use = function (plugin: Function | Object) {
    const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
    if (installedPlugins.indexOf(plugin) > -1) {
      return this
    }

    // additional parameters
    const args = toArray(arguments, 1)
    args.unshift(this)
    if (typeof plugin.install === 'function') {
      plugin.install.apply(plugin, args)
    } else if (typeof plugin === 'function') {
      plugin.apply(null, args)
    }
    installedPlugins.push(plugin)
    return this
  }
}
複製程式碼

the following is the source code of the toArray

export function toArray (list: any, start?: number): Array<any> {
  start = start || 0
  let i = list.length - start
  const ret: Array<any> = new Array(i)
  while (i--) {
    ret[i] = list[i + start]
  }
  return ret
}
複製程式碼

now you see it.

相關文章