vue中axios的几种封装技巧

2022-09-08 12:37:14

1.通过原型prototype给全局一个axios

        在src/main.js文件内引入axios,全局vue绑定一个$http指向axios

import axios from 'axios'

Vue.prototype.$http=axios

封装好处:全局使用$http代替axios,不用每次都import引入axios文件

等级:青铜

星级:❤❤

2.通过封装axios,请求拦截器,请求地址

  1. 在src下新建文件夹config/url.js    用于储存请求地址的链接url

        以电影网站为例:

//正在热映电影链接  注意后面的动态地址pageNum拼接接口
export const nowplayinglist=
'https://xxxx.com/xxxx?cityId=440300&pageSize=10&type=1&k=9428315&pageNum=';
//即将上映电影链接  注意后面的动态地址pageNum拼接接口
export const commingsoonlist=
"https://xxxx.com/xxxx?cityId=310100&pageSize=10&type=2&k=1915069&pageNum=";
//详情页面电影的信息地址
export const detalislist=
"https://xxxx.com/xxxx?k=3633812&filmId=";
//城市id 的电影院信息地址
export const cinemalist = 
"https://xxxx.com/xxxx?ticketFlag=1&k=8975302&cityId=";
//所有有电影院的城市列表信息地址
export const citylist =
"https://xxxx.com/xxxx?k=3233761";
//登录页面访问axios的信息地址
export const loginUrl =
 "http://xxxx:3000/login";

   2.对axios进行封装请求拦截器 在src创建文件api/http.js

import axios from 'axios'
//请求拦截器设置 两个参数 (成功时执行第一个参数config.headers{}代表请求拦截器的配置,失败时执行第二个) 
axios.interceptors.request.use(
    function(config){
        let host = ''
        let info = config.headers.info
        if(info=='info'){
            host='mall.film-ticket.film.info'
        }else if (info == "cinema") {
            // 影院列表
            host = "xxx.cinema.list";
            //所有城市的数据
        } else if (info == "city") {
            host = "xxx.city.list";
        } else {
            // 列表信息的头
            host = "xxx.film.list";
        }
        // 重点携带信息的位置头
        config.headers = {
            "X-Client-Info": '{"a":"3000","ch":"1002","v":"5.2.0","e":"xxx"}',
            "X-Host": host,
        };
        return config
    },
    function(error){
        console.log('请求拦截器设置失败')
    }
)
// 1 如果是没有请求拦截器配置 暴露的axios就是普通的axios 
// 2如果有请求拦截器的配置 暴露出的axios就是配置过 折腾过请求拦截器的axios 带有请求拦截器的
export default axios

3. 配置请求api  在src/api/api.js

//引入携带请求拦截器的封装后的axios请求头
import http from './http'
//引入封装好的请求连接地址URL 在src/config/url.js里面
import { nowplayinglist, commingsoonlist, detailslist, cinemalist, citylist,loginUrl} from '@/config/url'
//可以多个暴露模块  传参 修改请求头的默认信息 暴露出来的信息相当于 axios.get('url')
export const nowplayinglistDate = (page = 1) => {
    http.defaults.headers.info = ''
    return http.get(nowplayinglist + page)
}

export const commingsoonlistDate = (page = 1) => {
    http.defaults.headers.info = ''
    return http.get(commingsoonlist + page)
}

export const detalislistDate = (filmid) => {
    http.defaults.headers.info = 'info'
    return http.get(detailslist + filmid)
}

export const cinemalistData = (cityid) => {
    http.defaults.headers.info = 'cinema'
    return http.get(cinemalist + cityid)
}
//城市列表需要通过筛选 (不是所有字母开头都有影院)
export const citylistData = async () => {
    http.defaults.headers.info = 'city'
    //通过async 和await 异步向前挂载数据ret
    let ret = await http.get(citylist)
    var cities = ret.data.data.cities
    var codeList = []//26个英文字母
    for (let i = 65; i <= 90; i++) {
        codeList.push(String.fromCharCode(i))
    }
    var dataList = []  //城市的具体分类信息
    var indexList = []  //筛选后的城市的字母 
    codeList.forEach((element) => {
        let temArr=cities.filter((item) => {
            return item.pinyin.substr(0,1) == element.toLowerCase()
        })
        if(temArr.length){
            indexList.push(element)
            dataList.push({
                index:element,
                data:temArr
            })
        }
    })
    return {dataList,indexList}
}
//login 函数
export const userLogin = (data) => {
    //loginurl在上面引入了
    return http.post(loginUrl, data)    
}

4.请求访问的时候使用 使用的时候import引入文件调用接口 获取数据

import {userLogin} from '@/api/api'

mounted(){
    console.log('可以请求axios')
    let ret = await userLogin(this.formData)
    console.log('ret',ret)
}

封装好处:将请求地址和请求拦截器相结合封装axios,最后通过封装api 进行动态请求。当使用axios请求的时候导入api内部导出相应的模块(解构赋值),可以进行动态传参等拼接url。

等级:钻石

星级:❤❤❤❤

3.大佬级别封装axios

 1.在vue.config.js文件内配置,当请求axios地址中存在 /api 会自动在前面添加上target(前端跨域的设置,实现了前端跨域)

module.exports = {
    devServer: {
        proxy: {
            '/api': {
                target: 'http://127.0.0.1:3000',
                changeOrigin: true,
                // 查找到/api添加后如果需要去除/api的设置
                //   pathRewrite:{
                //      '/api':''
                //  }
            }
        }
    }
}

2. 在项目中创建两个文件:.env.development    和     .env.production

        在.env.development 中添加:

# 标志
ENV = 'development'

# base api
VUE_APP_BASE_API = '/api'

        在 .env.production中添加:

# 标志
ENV = 'production'

# base api
VUE_APP_BASE_API = '/prod-api'

 3.在src目录下创建utils/request.js

import axios from 'axios'

const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API,
  timeout: 5000
})

// 当外界调用这个接口axios请求 (自动拼接上/api)
// 相当于:
// const service=axios({
//     url:'/api/sys/login',
//     method:'POST',
//     data:data
// })

//此处可以设置请求拦截器和响应拦截器

// 登录响应拦截器
service.interceptors.response.use(
    (response)=>{
        const {info,code}=response.data
        if(info=='success'){
            return response.data
        }else{
            alert(info)
            if(code=='403'){
                store.dispatch('user/logout')
            }
        }
    },
    (err)=>{
        console.log(err);
    }
)
// 请求拦截器
service.interceptors.request.use(
    (config)=>{
        if (store.getters.token) {
            // 当有token的时候携带在请求头上 
            config.headers.Authorization = `Bearer ${store.getters.token}`
        }
        return config
    },  
    (err)=>{
        console.log(err);
    }
)

export default service

4.在src下面创建api/sys.js 用于拼劲/api和请求拦截器响应拦截器 导出请求接口提供使用

//引入封装的请求自动拼接/api和请求,响应拦截器
import request from '@/utils/request'
//导出各个模块的请求接口 可动态传入数据data接收
export const login = data => {
    return request({
        url: '/sys/login',
        method: 'POST',
        data
    })
}

export const register = data => {
    return request({
        url: '/sys/register',
        method: 'POST',
        data
    })
}

export const getUserInfo = () => {
    return request({
        url: '/sys/profile',
    })
}


export const getUserInfoList = (data) => {
    return request({
        url: '/sys/userlist',
        params: data
    })
}

export const getUsersearch = (query) => {
    return request({
        url: '/sys/getUsersearch',
        params: {
            mobile: query
        }
    })
}

export const addUser = (data) => {
    return request({
        url: '/sys/adduser',
        method: 'post',
        data: {
            data: data
        }
    })
}

export const updateuser = (data) => {
    return request({
        url: '/sys/update',
        method: 'post',
        data: {
            data: data
        }
    })
}


export const deluser = (data) => {
    return request({
      url: '/sys/deluser',
      method: 'post',
      data:{
        data:data
      }
    })
  }

 5.当需要使用的时候(可以配合vuex模块化更加细致的使用通过Promise传值)

//引入封装的模块
import { login} from '@/api/sys'
login({
      mobile: username,
      password: password
      // 传出去的数据被login里面data接受了
      // axios异步请求回来的数据.then 获得
      }).then((res) => {
             console.log(res)
       }).catch((err) => {
            console.log(err)
       }
})

封装好处:通过vue.config.js文件内 对请求时带有/api的axios封装 在 配合vuex等进行多功能的axios请求,模块化清晰,便于维护,逻辑的整合。

等级:王者1星

星级:❤❤❤❤❤❤❤❤❤❤

4.max顶配版本封装全面解析

尽情期待...

等级:荣耀王者101

星级:满天星※

  • 作者:李大将军QN
  • 原文链接:https://blog.csdn.net/weixin_51444162/article/details/123652733
    更新时间:2022-09-08 12:37:14