1. 程式人生 > 實用技巧 >vue專案初始化

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;