国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

【Vue項(xiàng)目總結(jié)】后臺(tái)管理項(xiàng)目總結(jié)

codeKK / 2921人閱讀

摘要:公司做的大部分都是后臺(tái)管理項(xiàng)目,剔除每個(gè)項(xiàng)目的業(yè)務(wù)邏輯,其實(shí)都可以用通用的一套模版來(lái)做。總結(jié)以上都是后臺(tái)系統(tǒng)中可以用到的一些處理方式,具體代碼可查看。其他總結(jié)文章常規(guī)打包優(yōu)化方案組件通信處理方案

公司做的大部分都是后臺(tái)管理項(xiàng)目,剔除每個(gè)項(xiàng)目的業(yè)務(wù)邏輯,其實(shí)都可以用通用的一套模版來(lái)做。

登錄邏輯

每個(gè)系統(tǒng)都有自己的登錄登出邏輯,而我們前端所要做的其實(shí)是請(qǐng)求后臺(tái),拿到登錄權(quán)限,帶上登錄權(quán)限,獲取用戶(hù)信息和菜單信息。
vue項(xiàng)目開(kāi)發(fā)當(dāng)中,我們一般都是在全局路由鉤子做這一系列判斷。

router.beforeEach(async(to, from, next) => {
  NProgress.start();
  await store.dispatch("SetConfigApi"); // 獲取配置
  await store.dispatch("SetApi"); // 設(shè)置基本配置
  const token = await store.dispatch("getToken"); // 獲取token
  if (token) {
    // 用戶(hù)信息不存在
    if (!store.getters.userInfo) {
      await store.dispatch("GetUser"); // 獲取用戶(hù)信息
      const menuList = await store.dispatch("GetMenu", localRoute); // 獲取菜單
      await store.dispatch("GenerateRoutes", localRoute);
      router.addRoutes(store.getters.addRoutes);
      ...
    } else {
      next();
    }
  } else {
    if (whiteList.includes(to.path)) {
      // 在免登錄白名單,直接進(jìn)入
      next();
    } else {
      window.location.href = store.getters.api.IPORTAL_LOCAL_API;
      NProgress.done();
    }
  }
});

當(dāng)用戶(hù)進(jìn)入系統(tǒng)的時(shí)候,先獲取系統(tǒng)的配置信息,這個(gè)配置信息可以是前端json文件,或者是后臺(tái)接口;用這種方式可以靈活的修改項(xiàng)目中的配置,而不用每次都打包死進(jìn)入項(xiàng)目,直接可以要運(yùn)維童靴修改對(duì)應(yīng)的配置信息,就可以了。

菜單權(quán)限

以前的菜單路由是直接寫(xiě)死在前端,但是當(dāng)我們直接訪問(wèn)這個(gè)路由時(shí),用戶(hù)還是可以進(jìn)入到這個(gè)功能頁(yè)面;后來(lái)直接改成動(dòng)態(tài)添加路由的方式router.addRoutes

前端先獲取菜單列表

根據(jù)獲取的菜單列表循環(huán)添加用戶(hù)菜單路由集合

動(dòng)態(tài)添加路由

具體可查看

請(qǐng)求方案

項(xiàng)目請(qǐng)求是使用的axios,可以對(duì)它添加攔截器來(lái)處理我們的請(qǐng)求,也可以處理通過(guò)axios.CancelToken重復(fù)請(qǐng)求,具體可看代碼:

// 設(shè)置請(qǐng)求統(tǒng)一信息
import axios from "axios";
import store from "@/store/index.js";
import qs from "qs";
import { messages } from "./msg-box.js";

const service = axios.create({
  timeout: 300000, // 超時(shí)設(shè)置
  withCredentials: true // 跨域請(qǐng)求
});

let hasLogoutStatus = false; // 是否某個(gè)請(qǐng)求存在需要退出的狀態(tài)

const queue = []; // 請(qǐng)求隊(duì)列

const CancelToken = axios.CancelToken; // axios內(nèi)置的中斷方法

/**
 * 拼接請(qǐng)求的url和方法;
 * 同樣的`url + method` 可以視為相同的請(qǐng)求
 * @param {Object} config 請(qǐng)求頭對(duì)象
 */
const token = config => {
  return `${config.url}_${config.method}`;
};

/**
 * 中斷重復(fù)的請(qǐng)求,并從隊(duì)列中移除
 * @param {Object} config 請(qǐng)求頭對(duì)象
 */
const removeQueue = config => {
  for (let i = 0, size = queue.length; i < size; i++) {
    const task = queue[i];
    if (!task) return;
    // 出現(xiàn)401,403狀態(tài)碼中斷后續(xù)請(qǐng)求
    const isLogout = token(config).includes("logout");
    // 退出接口跳過(guò)中斷邏輯
    if (!isLogout && hasLogoutStatus) {
      task.token();
      queue.splice(i, 1);
    } else {
      const cancelMethods = ["post", "put", "delete"]; // 需要中斷的請(qǐng)求方式
      const { method } = config;
      if (cancelMethods.includes(method)) {
        if (task.token === token(config)) {
          task.cancel();
          queue.splice(i, 1);
        }
      }
    }
  }
};

/**
 * 請(qǐng)求錯(cuò)誤統(tǒng)一處理
 * @param {Object} response 錯(cuò)誤對(duì)象
 */
const errorHandle = response => {
  // eslint-disable-next-line prettier/prettier
  const { status, data: { message = "" }} = response;
  let msg = message;
  if (!message) {
    switch (status) {
      case 401:
        msg = "您沒(méi)有權(quán)限訪問(wèn)此操作!";
        break;
      case 403:
        msg = "您的登錄狀態(tài)已失效,請(qǐng)重新登錄。";
        break;
      case 424:
        msg = response.data.error;
        break;
      default:
        msg = "服務(wù)請(qǐng)求異常,請(qǐng)刷新重試。";
    }
  }
  hasLogoutStatus = status === 401 || status === 403;
  if (hasLogoutStatus) {
    messages("error", msg, () => {
      store.dispatch("Logout");
    });
  }
  messages("error", msg);
};

// 請(qǐng)求攔截器
service.interceptors.request.use(
  config => {
    // 中斷之前的同名請(qǐng)求
    removeQueue(config);
    // 添加cancelToken
    config.cancelToken = new CancelToken(c => {
      queue.push({ token: token(config), cancel: c });
    });
    // 登錄后添加token
    if (store.getters.token) {
      config.headers["Authorization"] =
        store.getters.token.token_type + " " + store.getters.token.access_token;
    }
    return config;
  },
  error => {
    return Promise.reject(error);
  }
);

// 響應(yīng)攔截器
service.interceptors.response.use(
  response => {
    // 在請(qǐng)求完成后,自動(dòng)移出隊(duì)列
    removeQueue(response.config);
    // 關(guān)閉全局按鈕Loading響應(yīng)
    store.dispatch("CancalLoading");
    // 錯(cuò)誤碼處理
    if (response.status !== 200) {
      return Promise.reject(response);
    }
    return response;
  },
  error => {
    const { response } = error;
    if (response) {
      // 錯(cuò)誤處理
      errorHandle(response);
      return Promise.reject(response);
    } else {
      // 請(qǐng)求超時(shí)
      if (error.message.includes("timeout")) {
        console.log("超時(shí)了");
        messages("error", "請(qǐng)求已超時(shí),請(qǐng)刷新或檢查互聯(lián)網(wǎng)連接");
      } else {
        // 斷網(wǎng),可以展示斷網(wǎng)組件
        console.log("斷網(wǎng)了");
        messages("error", "請(qǐng)檢查網(wǎng)絡(luò)是否已連接");
      }
    }
  }
);

export default {
  get: (url, data = {}) => {
    return new Promise((resolve, reject) => {
      service
        .get(store.getters.api.API + url, { params: data })
        .then(response => {
          resolve(response.data);
        })
        .catch(error => {
          reject(error);
        });
    }).catch(error => {
      throw new Error(error);
    });
  },
  post: (url, data = {}) => {
    return new Promise((resolve, reject) => {
      service
        .post(store.getters.api.API + url, data, {
          headers: {
            "Content-Type": "application/x-www-form-urlencoded;charset=utf-8"
          },
          withCredentials: true,
          transformRequest: [
            data => {
              return qs.stringify(data);
            }
          ]
        })
        .then(response => {
          resolve(response.data);
        })
        .catch(error => {
          reject(error);
        });
    }).catch(error => {
      return Promise.reject(error);
    });
  },
  ...
  /**
   * blob下載
   * @param {String} url 請(qǐng)求地址
   * @param {String} method 請(qǐng)求方式 默認(rèn)`get`
   * @param {Object} data 請(qǐng)求數(shù)據(jù)
   */
  exportFile({ url = "", data = {}, method = "get" }) {
    return new Promise((resolve, reject) => {
      const isPost =
        method.toLocaleUpperCase() === "POST"
          ? {
            headers: { "Content-Type": "application/json" },
            data
          }
          : {
            params: data
          };
      const downConfig = {
        withCredentials: true,
        responseType: "blob",
        ...isPost
      };
      service
        // eslint-disable-next-line no-unexpected-multiline
        [method](store.getters.api.API + url, downConfig)
        .then(response => {
          resolve(response);
        })
        .catch(error => {
          reject(error);
        });
    }).catch(error => {
      return Promise.reject(error);
    });
  }
};

當(dāng)需要使用請(qǐng)求時(shí),可以引用文件http.js,也可以掛在到vue原型上,在組件內(nèi)使用this.$http

// user.js
import http from "@/utils/http.js";

export function getUser() {
  return http.get("/user");
}

// main.js
Vue.prototype.$http = http;
按鈕Loading處理

按鈕的loading效果可以處理后臺(tái)響應(yīng)時(shí)間有點(diǎn)長(zhǎng)場(chǎng)景,這里使用store封裝了下處理方式。

// loading.js
import Vue from "vue";

const loading = {
  state: {},
  mutations: {
    SET_LOADING: (state, data) => {
      const isObject =
        Object.prototype.toString.call(data) === "[object Object]";
      if (!isObject) return;
      Object.keys(data).forEach(key => {
        Vue.set(state, key, data[key]);
      });
    },
    CANCAL_LOADING: state => {
      Object.keys(state).forEach(key => {
        Vue.delete(state, key);
      });
    }
  },
  actions: {
    SetLoading({ commit }, data) {
      commit("SET_LOADING", data);
    },
    CancalLoading({ commit }, data) {
      commit("CANCAL_LOADING", data);
    }
  }
};

export default loading;

// http.js
service.interceptors.response.use(
  response => {
    // 關(guān)閉全局按鈕Loading響應(yīng)
    store.dispatch("CancalLoading");
    ...
})    

在組件內(nèi)定義

保存

computed: {
    btn() {
        return this.$store.state.loading;
    }
}
methods: {
    handleClick() {
        this.$store.dispatch("SetLoading", { save: true });    
    }
}

以上就可以完美的使用loading,而不用每個(gè)都在data中定義了。

總結(jié)

以上都是后臺(tái)系統(tǒng)中可以用到的一些處理方式,具體代碼可查看。

其他總結(jié)文章:

webpack常規(guī)打包優(yōu)化方案

組件通信處理方案

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/104839.html

相關(guān)文章

  • Vue項(xiàng)目總結(jié)項(xiàng)目nginx部署

    摘要:項(xiàng)目開(kāi)發(fā)完成,接下來(lái)是上線,關(guān)于項(xiàng)目的部署,我司前端是部署在服務(wù)器上,關(guān)于的相關(guān)文檔,請(qǐng)自行查閱本文只記錄部署時(shí)碰到的一些問(wèn)題。其他總結(jié)文章常規(guī)打包優(yōu)化方案組件通信處理方案后臺(tái)管理項(xiàng)目總結(jié) 項(xiàng)目開(kāi)發(fā)完成,接下來(lái)是上線,關(guān)于vue項(xiàng)目的部署,我司前端是部署在nginx服務(wù)器上,關(guān)于nginx的相關(guān)文檔,請(qǐng)自行查閱;本文只記錄部署時(shí)碰到的一些問(wèn)題。 打包 vue項(xiàng)目打包后,是生成一系列的靜...

    CntChen 評(píng)論0 收藏0
  • Vue項(xiàng)目總結(jié)】基于餓了么組件封裝

    摘要:項(xiàng)目中,組件是項(xiàng)目的基石,每個(gè)頁(yè)面都是組件來(lái)組裝起來(lái),我司沒(méi)有自己的組件庫(kù),選用的是組件庫(kù),在它的基礎(chǔ)上再次封裝。部分代碼三級(jí)效果如下總結(jié)組件是項(xiàng)目的積木條,公用組件的封裝成功與否其實(shí)是對(duì)項(xiàng)目的開(kāi)發(fā)效率有直接影響。 vue項(xiàng)目中,組件是項(xiàng)目的基石,每個(gè)頁(yè)面都是組件來(lái)組裝起來(lái),我司沒(méi)有自己的組件庫(kù),選用的是ElementUI組件庫(kù),在它的基礎(chǔ)上再次封裝。 可編輯表格 由于是后臺(tái)管理項(xiàng)目,...

    YPHP 評(píng)論0 收藏0
  • Vue 2.x 實(shí)戰(zhàn)之后臺(tái)管理系統(tǒng)開(kāi)發(fā)(二)

    摘要:導(dǎo)語(yǔ)承接上文實(shí)戰(zhàn)之后臺(tái)管理系統(tǒng)開(kāi)發(fā)一在上一篇文章中,我詳細(xì)敘述了如何創(chuàng)建項(xiàng)目框架和引入各種后臺(tái)常用插件,做好這些準(zhǔn)備工作后,我們就可以著手進(jìn)行頁(yè)面的開(kāi)發(fā)了。如果傳入的數(shù)據(jù)不符合規(guī)格,會(huì)發(fā)出警告。 1. 導(dǎo)語(yǔ) 承接上文:Vue 2.x 實(shí)戰(zhàn)之后臺(tái)管理系統(tǒng)開(kāi)發(fā)(一) 在上一篇文章中,我詳細(xì)敘述了如何創(chuàng)建項(xiàng)目框架和引入各種后臺(tái)常用插件,做好這些準(zhǔn)備工作后,我們就可以著手進(jìn)行頁(yè)面的開(kāi)發(fā)了。在開(kāi)...

    Ilikewhite 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<