vue项目初始化

vue.config.js

主要内容:适配、开发环境打包压缩、文件夹别名、跨域处理

插件:terser-webpack-plugin,postcss-px2rem

const path = require("path");
const TerserPlugin = require("terser-webpack-plugin");
const px2rem = require("postcss-px2rem");
const postcss = px2rem({
  // 基准大小 baseSize,需要和rem.js中相同
  remUnit: 16
});
module.exports = {
  publicPath: "./", // 基本路径
  outputDir: "dist", // 输出文件目录
  lintOnSave: false, // eslint-loader 是否在保存的时候检查
  // webpack配置
  configureWebpack: config => {
    if (process.env.NODE_ENV === "production") {
      // 为生产环境修改配置...
      config.mode = "production";
      // 将每个依赖包打包成单独的js文件
      let optimization = {
        runtimeChunk: "single",
        splitChunks: {
          chunks: "all",
          maxInitialRequests: Infinity,
          minSize: 20000,
          cacheGroups: {
            vendor: {
              test: /[\\/]node_modules[\\/]/,
              name(module) {
                // get the name. E.g. node_modules/packageName/not/this/part.js
                // or node_modules/packageName
                const packageName = module.context.match(
                  /[\\/]node_modules[\\/](.*?)([\\/]|$)/
                )[1];
                // npm package names are URL-safe, but some servers don't like @ symbols
                return `npm.${packageName.replace("@", "")}`;
              }
            }
          }
        },
        minimizer: [
          new TerserPlugin({
            cache: true,
            parallel: true,
            sourceMap: true,
            terserOptions: {
              compress: {
                warnings: false,
                drop_console: true, // console
                drop_debugger: false,
                pure_funcs: ["console.log"] // 移除console
              }
            }
          })
        ]
      };
      Object.assign(config, {
        optimization
      });
    } else {
      // 为开发环境修改配置...
      config.mode = "development";
    }
    Object.assign(config, {
      // 开发生产共同配置
      resolve: {
        alias: {
          "@": path.resolve(__dirname, "./src"),
          "@c": path.resolve(__dirname, "./src/components"),
          "@api": path.resolve(__dirname, "./src/api")
        } // 别名配置
      }
    });
  },
  productionSourceMap: true, // 生产环境是否生成 sourceMap 文件
  // css相关配置
  css: {
    sourceMap: false,
    loaderOptions: {
      css: {},
      scss: {},
      postcss: {
        plugins: process.env.NODE_ENV === "production" ? [postcss] : []
      }
    },
    requireModuleExtension: false
  },
  parallel: require("os").cpus().length > 1, // 是否为 Babel 或 TypeScript 使用 thread-loader。该选项在系统的 CPU 有多于一个内核时自动启用,仅作用于生产构建。
  pwa: {}, // PWA 插件相关配置
  // webpack-dev-server 相关配置
  devServer: {
    open: process.platform === "darwin",
    host: "0.0.0.0", // 允许外部ip访问
    port: 8022, // 端口
    https: false, // 启用https
    overlay: {
      warnings: true,
      errors: true
    }, // 错误、警告在页面弹出
    proxy: {
      "/api": {
        target: process.env.VUE_APP_DATA_API,
        changeOrigin: true, // 允许websockets跨域
        ws: true, //ws跨域
        pathRewrite: {
          "^/api": ""
        }
      }
    } // 代理转发配置,用于调试环境
  },
  // 第三方插件配置
  pluginOptions: {}
};

适配注意:需要在main.js中做缩放处理,一般会将文件封装抽离出来

// rem等比适配配置文件
// 基准大小
const baseSize = 16
// 设置 rem 函数
function setRem () {
  // 当前页面宽度相对于 1920宽的缩放比例,可根据自己需要修改。
  const scale = document.documentElement.clientWidth / 1920
  // 设置页面根节点字体大小(“Math.min(scale, 2)” 指最高放大比例为2,可根据实际业务需求调整)
  document.documentElement.style.fontSize = baseSize * Math.min(scale, 2) + 'px'
}
// 初始化
setRem()
// 改变窗口大小时重新设置 rem
window.onresize = function () {
  setRem()
}

 

babel.config.js

主要内容:babel语法翻译,这里主要兼容es10 ?. 语法

插件:@babel/plugin-proposal-optional-chaining

module.exports = {
  presets: ['@vue/app'],
  plugins: ['@babel/plugin-proposal-optional-chaining']
}

util

js-cookie二次封装

import Cookie from "js-cookie";

const cookie = {};
//存储cookie
cookie.set = function(name = "default", value = "", setting = {}) {
  var realSetting = {
    expires: 1
  };
  Object.assign(realSetting, setting);
  return Cookie.set(`mp-${name}`, value, realSetting);
};
//拿到cookie
cookie.get = function(name = "default") {
  return Cookie.get(`mp-${name}`);
};
//全部的cookie值
cookie.getAll = function() {
  return Cookie.get();
};
//移除cookie
cookie.remove = function(name = "default") {
  return Cookie.remove(`mp-${name}`);
};

export default cookie;

 

axios二次封装

插件:axios,qs

1、创建实例 =》 axios.create(Object)

2、请求拦截 =》 axios实例.interceptors.request.use(Fn<config>,Fn<err>)

3、响应拦截 =》 axios实例.interceptors.response.use(Fn<res>,Fn<err>)

import axios from "axios";
import cookie from "./cookie";
import { stringify } from "qs";
import { Message } from "element-ui";

// status错误信息
function getStatusMsg(status) {
  switch (status) {
    case 400:
      return "请求错误";
    case 401:
      cookie.remove("token");
      window.location = "/#/login";
      return "未授权,请登录";
    case 403:
      return "拒绝访问";
    case 404:
      return "请求地址出错";
    case 408:
      return "请求超时";
    case 500:
      return "服务器内部错误";
    case 501:
      return "服务未实现";
    case 502:
      return "网关错误";
    case 503:
      return "服务不可用";
    case 504:
      return "网关超时";
    case 505:
      return "HTTP版本不受支持";
    default:
      return "";
  }
}

// 错误处理
/*
 *错误处理
 *@params from :来源
 *@params code :code值
 *@params msg :错误信息
 */

function catchError(from, msg) {
  let isDev = process.env.NODE_ENV === "development";
  // 统一抛出异常
  if (isDev) {
    return Message({ message: msg, type: "error", duration: 2 * 1000 });
  } else {
    if (from === "code") {
      // 抛出与后端规定的异常
      return Message({ message: msg, type: "error", duration: 5 * 1000 });
    } else {
      // 手动处理异常
      throw msg;
    }
  }
}

function createService(baseURL = "127.0.0.1") {
  // 创建一个 axios 实例
  const service = axios.create({
    baseURL,
    timeout: 60000 // 请求超时时间
  });

  // 请求拦截器
  service.interceptors.request.use(
    config => {
      // 如果参数isRealPost属性为真,为真正的post参数
      if (!config.isRealPost) {
        config.paramsSerializer = function(params) {
          return stringify(params, { indices: false });
        };
      }
      config.headers["Content-Type"] = "application/json; charset=UTF-8";
      return config;
    },
    error => {
      catchError("status", error.message);
    }
  );

  // 响应拦截器
  service.interceptors.response.use(
    response => {
      let { data, code, msg } = response.data;
      switch (code) {
        case 200:
          return data || response.data;
        case 401:
          window.location = "/#/login";
          break;
        case 500:
          catchError("code", msg);
          break;
        default:
          console.log("其他code值需重新定义");
          console.log(msg);
          catchError("status", msg);
          return response.data;
      }
    },
    error => {
      let msg = getStatusMsg(error.response.status);
      catchError("status", msg);
    }
  );
  return service;
}

export default createService;

路由

import Vue from "vue";
import VueRouter from "vue-router";
import NProgress from "nprogress";
import "nprogress/nprogress.css";
import { cookie } from "@/util";
import routes from "./routes";
Vue.use(VueRouter);

const router = new VueRouter({
  routes
});
router.beforeEach((to, from, next) => {
  NProgress.start();
  var isLogin = cookie.get("token");
  var isToLogin = to.name === "Login";
  //登录判断
  if (isToLogin || isLogin) {
    next();
  } else {
    next({
      name: "Login",
      redirect: true
    });
  }
  NProgress.done();
});
router.afterEach(to => {
  let metaTitle = to.meta.title || "";
  let title = process.env.VUE_APP_TITLE + (metaTitle ? ` | ${metaTitle}` : "");
  document.title = title;
  NProgress.done();
});

export default router;

 

posted @ 2020-11-03 19:46  良荣十贰  阅读(372)  评论(0)    收藏  举报