VUE封装axios(webpack配置)

axios封装

文件创建位置依个人喜好,我将axios的封装写在了public文件夹中 - fetch.js


在这里插入图片描述

文件代码!

import axios from "axios";
axios.defaults.headers.post["Content-Type"] = "application/json";
axios.defaults.headers.put["Content-Type"] = "application/json";
// baseurl 就是 在 .env.development 和 .env.development.local 中 预设的域名
console.log("baseUrl:", process.env.VUE_APP_URL); // => 'https://api.apiopen.top/'
let baseurl =
  process.env.VUE_APP_TITLE === "local" // 通过判断 当前的环境变量 得知 项目 运行在 本地 或者 线上
    ? process.env.VUE_APP_PROXY // 本地 使用代理 => '/dev' 此处在 vue.config.js 中代理请求处有配置
    : process.env.VUE_APP_URL; // 线上 使用域名 => 'https://api.apiopen.top/'
axios.defaults.baseURL = baseurl; // 将 baseurl 设置为 axios 的默认 baseURL
/**
 * 下面 是 axios 封装的 请求
 * 采用 es6 promise 和 async await 方式
 */
export default async (url = "", data = {}, type = "POST") => {
  type = type.toUpperCase();
  /**
   * get 请求
   */
  if (type == "GET") {
    //请求参数 拼接字符串
    /**为了实现restful风格,在get请求后,拼接id
    *参数 {id:"id",param:{其他参数}}
    */
    data.id ? (url = url + "/" + data.id) : (url = url);
    if (data.param) {
      let dataStr = [];
      Object.keys(data.param).forEach((key) => {
        dataStr.push(key + "=" + data.param[key]);
      });
      if (dataStr.length) {
        dataStr = dataStr.join("&");
        url += "?" + dataStr;
      }
    }

    return new Promise((resolve, reject) => {
      axios
        .get(url)
        .then((res) => {
          resolve(res);
        })
        .catch((err) => {
          reject(err);
        });
    });
  }
  /**
   * post 请求
   */
  if (type == "POST") {
    return new Promise((resolve, reject) => {
      data = JSON.stringify(data);
      axios
        .post(url, data)
        .then((res) => {
          resolve(res);
        })
        .catch((err) => {
          reject(err);
        });
    });
  }
  if (type == "PUT") {
    data.id ? (url = url + "/" + data.id) : (url = url);
    return new Promise((resolve, reject) => {
      data = JSON.stringify(data.data || data);
      axios
        .put(url, data)
        .then((res) => {
          resolve(res);
        })
        .catch((err) => {
          reject(err);
        });
    });
  }
  if (type == "DELETE") {
    data.id ? (url = url + "/" + data.id) : (url = url);
    return new Promise((resolve, reject) => {
      data = JSON.stringify(data.data);
      axios
        .delete(url, data)
        .then((res) => {
          console.log(res);
          resolve(res);
        })
        .catch((err) => {
          console.log(err);
          reject(err);
        });
    });
  }
};

拦截器

请求和相应拦截器在main.js中配置

请求拦截器

axios.interceptors.request.use(
  function(config) {
    // 在发送请求之前做些什么
    loading = Vue.prototype.$loading({
      lock: true,
      text: "客官请稍后....",
      spinner: "el-icon-loading",
      background: "rgba(0, 0, 0, 0.7)",
    });

    //!    验证是否登录

    if (sessionStorage.getItem("Authorization") === null) {
      router.replace({
        path: "/",
      });
    }

    if (sessionStorage["Authorization"] === undefined)
      router.replace({
        path: "/",
      });
    else
      config.headers.common["Authorization"] = sessionStorage["Authorization"];

    return config;
  },
  function(error) {
    loading.close();
    // 对请求错误做些什么
    return Promise.reject(error);
  }
);

响应拦截器

axios.interceptors.response.use(
  function(response) {
    if ("Authorization" in response.headers)
      sessionStorage["Authorization"] = response.headers.Authorization;

    if (response.data.errorCode === 401) {
      Vue.prototype.$message.error(response.data.message);
      router.replace({
        path: "/login",
      });
    }

    if (sessionStorage.getItem("Authorization") === null) {
      router.replace({
        path: "/login",
      });
    }

    loading.close();

    return response;
  },
  function(error) {
    loading.close();
    if (error.response.status >= 500) {
      Vue.prototype.$message.error("服务异常,稍后重试 !");
    } else if (error.response.status === 401) {
      router.replace({
        path: "/login",
      });
      Vue.prototype.$message.error("登录超时,请重新登录!");
    }
    return Promise.reject(error);
  }
);

将所有接口API统一管理

在这里插入图片描述

引入封装好的axios

// 引入 封装请求
import fetch from "../public/fetch.js";

接口export示例

export const getData = (data) => fetch("getData", data, "get");

接口调用示例

async getOilMark(){
    const res = await getData({id:1,param:{test:123}});
}

vue.config.js

const path = require("path");
function resolve(dir) {
  return path.join(__dirname, dir);
}
console.log("接口地址:", process.env.VUE_APP_URL)

const CompressionPlugin = require("compression-webpack-plugin"); //Gzip
module.exports = {
  // 基本路径
  publicPath: "./",

  // 输出文件目录
  outputDir: "dist",

  // 放置生成的静态资源 (js、css、img、fonts) 的 (相对于 outputDir 的) 目录。
  assetsDir: "static",

  // eslint-loader 是否在保存的时候检查
  lintOnSave: false,

  // 如果机器有超过1个内核,则在默认情况下为生产构建中的babel&ts使用线程加载器
  parallel: require("os").cpus().length > 1,

  // 生产环境是否生成 sourceMap 文件,一般情况不建议打开
  productionSourceMap: false,

  // PWA 插件相关配置 see https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-pwa
  pwa: {},

  // webpack配置 see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md
  chainWebpack: config => {
    // 别名配置 可进行 链式操作
    config.resolve.alias
      .set("@", resolve("src"))
      .set("views", resolve("src/views"))
      .set("$img", resolve("src/assets"));
  },

  //调整 webpack 配置 https://cli.vuejs.org/zh/guide/webpack.html#%E7%AE%80%E5%8D%95%E7%9A%84%E9%85%8D%E7%BD%AE%E6%96%B9%E5%BC%8F
  configureWebpack: config => {
    // 入口文件
    config.entry = "./src/main.js";
    // 生产 & 测试环境
    let pluginsPro = [
      new CompressionPlugin({
        //文件开启Gzip,也可以通过服务端(如:nginx)(https://github.com/webpack-contrib/compression-webpack-plugin)
        filename: "[path].gz[query]",
        algorithm: "gzip",
        test: new RegExp("\\.(" + ["js", "css"].join("|") + ")$"),
        threshold: 8192,
        minRatio: 0.8
      })
    ];
    // 为生产环境修改配置...process.env.NODE_ENV !== 'development'
    if (process.env.NODE_ENV !== "development") {
      config.plugins = [...config.plugins, ...pluginsPro];
    }
    // 打包上线 清除 所有 console
    if (process.env.NODE_ENV === "production") {
      config.optimization.minimizer[0].options.terserOptions.compress.drop_console = true;
    }
  },

  // 入口文件 可 单独进行配置 写法如下
  // configureWebpack: {
  //   entry: './src/view/index/main.js',
  // },

  // css相关配置
  css: {
    // 是否使用css分离插件 ExtractTextPlugin
    extract: true,
    // 开启 CSS source maps?
    sourceMap: false,
    // css预设器配置项
    loaderOptions: {},
    // 启用 CSS modules for all css / pre-processor files.
    modules: false
  },

  // webpack-dev-server 相关配置
  devServer: {
    open: true, // 是否 自动打开浏览器 在项目启动的时候
    host: "",
    port: 8080, // 端口
    https: false,
    hotOnly: false,

    // 设置代理
    // 这里设置了两个代理请求 为了匹配 不同环境的, 根据实际情况配置代理
    // 比如 公司有 开发 连调 测试 演示 生产等环境, 除了生产环境以外其他环境都需要配置 代理请求
    // 当启动 vue 项目的 时候 运行在 localhost:8080 上,假设公司的 开发环境 为 http://development.com 当发送请求时 就会发生跨域, 所以 采用代理方式 进行 同域,
    // 当 项目上线 后 根据 环境变量 使用不同 的域名 就不会有跨域情况
    // 读到这里 如果 还有 不理解 请往下进行
    proxy: {
      "/dev": {
        target: process.env.VUE_APP_URL, // 代理请求的地址 => https://api.apiopen.top/
        changeOrigin: true,
        pathRewrite: {
          "^/dev": ""
        }
      },
      "/api": {
        target: process.env.VUE_APP_URL,
        changeOrigin: true,
        pathRewrite: {
          "^/api": ""
        }
      }
    }
  },
  // 第三方插件配置
  pluginOptions: {}
};

不同环境的配置文件格式

在这里插入图片描述
NODE_ENV=development
VUE_APP_TITLE=local
VUE_APP_URL=localhost:8080/
VUE_APP_PROXY=/api
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,490评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,581评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,830评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,957评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,974评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,754评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,464评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,357评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,847评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,995评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,137评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,819评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,482评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,023评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,149评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,409评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,086评论 2 355

推荐阅读更多精彩内容