使用 Vue 总结出的后台管理项目模板(前端vue项目总结)

公司业务做的大部分都是后台管理项目,如果剔除掉项目中的业务逻辑,其实都可以用通用的一套模版来做。

登录逻辑

每个系统都有自己的登录登出逻辑,而我们前端所要做的其实是请求后台,拿到登录权限,带上登录权限,获取用户信息和菜单信息。 在vue项目开发当中,我们一般都是在全局路由钩子做这一系列判断。

router.beforeEach(async(to, from, next) => {  NProgress.start();  await store.dispatch('SetConfigApi'); // 获取配置  await store.dispatch('SetApi'); // 设置基本配置  const token = await store.dispatch('getToken'); // 获取token  if (token) {    // 用户信息不存在    if (!store.getters.userInfo) {      await store.dispatch('GetUser'); // 获取用户信息      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)) {      // 在免登录白名单,直接进入      next();    } else {      window.location.href = store.getters.api.IPORTAL_LOCAL_API;      NProgress.done();    }  }});

当用户进入系统的时候,先获取系统的配置信息,这个配置信息可以是前端json文件,或者是后台接口;用这种方式可以灵活的修改项目中的配置,而不用每次都打包死进入项目,直接可以要运维童靴修改对应的配置信息,就可以了。

菜单权限

以前的菜单路由是直接写死在前端,但是当我们直接访问这个路由时,用户还是可以进入到这个功能页面;后来直接改成动态添加路由的方式router.addRoutes

  1. 前端先获取菜单列表
  2. 根据获取的菜单列表循环添加用户菜单路由集合
  3. 动态添加路由

具体可查看

请求方案

项目请求是使用的axios,可以对它添加拦截器来处理我们的请求,也可以处理通过axios.CancelToken重复请求,具体可看代码:

// 设置请求统一信息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, // 超时设置  withCredentials: true // 跨域请求});let hasLogoutStatus = false; // 是否某个请求存在需要退出的状态const queue = []; // 请求队列const CancelToken = axios.CancelToken; // axios内置的中断方法/** * 拼接请求的url和方法; * 同样的`url   method` 可以视为相同的请求 * @param {Object} config 请求头对象 */const token = config => {  return `${config.url}_${config.method}`;};/** * 中断重复的请求,并从队列中移除 * @param {Object} config 请求头对象 */const removeQueue = config => {  for (let i = 0, size = queue.length; i < size; i ) {    const task = queue[i];    if (!task) return;    // 出现401,403状态码中断后续请求    const isLogout = token(config).includes('logout');    // 退出接口跳过中断逻辑    if (!isLogout && hasLogoutStatus) {      task.token();      queue.splice(i, 1);    } else {      const cancelMethods = ['post', 'put', 'delete']; // 需要中断的请求方式      const { method } = config;      if (cancelMethods.includes(method)) {        if (task.token === token(config)) {          task.cancel();          queue.splice(i, 1);        }      }    }  }};/** * 请求错误统一处理 * @param {Object} response 错误对象 */const errorHandle = response => {  // eslint-disable-next-line prettier/prettier  const { status, data: { message = '' }} = response;  let msg = message;  if (!message) {    switch (status) {      case 401:        msg = '您没有权限访问此操作!';        break;      case 403:        msg = '您的登录状态已失效,请重新登录。';        break;      case 424:        msg = response.data.error;        break;      default:        msg = '服务请求异常,请刷新重试。';    }  }  hasLogoutStatus = status === 401 || status === 403;  if (hasLogoutStatus) {    messages('error', msg, () => {      store.dispatch('Logout');    });  }  messages('error', msg);};// 请求拦截器service.interceptors.request.use(  config => {    // 中断之前的同名请求    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);  });// 响应拦截器service.interceptors.response.use(  response => {    // 在请求完成后,自动移出队列    removeQueue(response.config);    // 关闭全局按钮Loading响应    store.dispatch('CancalLoading');    // 错误码处理    if (response.status !== 200) {      return Promise.reject(response);    }    return response;  },  error => {    const { response } = error;    if (response) {      // 错误处理      errorHandle(response);      return Promise.reject(response);    } else {      // 请求超时      if (error.message.includes('timeout')) {        console.log('超时了');        messages('error', '请求已超时,请刷新或检查互联网连接');      } else {        // 断网,可以展示断网组件        console.log('断网了');        messages('error', '请检查网络是否已连接');      }    }  });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 请求地址   * @param {String} method 请求方式 默认`get`   * @param {Object} data 请求数据   */  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);    });  }};

当需要使用请求时,可以引用文件http.js,也可以挂载到vue原型上,在组件内使用this.$http

// user.jsimport http from '@/utils/http.js';export function getUser() {  return http.get('/user');}// main.jsVue.prototype.$http = http;

按钮Loading处理

按钮的loading效果可以处理后台响应时间有点长场景,这里使用store封装了下处理方式。

// loading.jsimport 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.jsservice.interceptors.response.use(  response => {    // 关闭全局按钮Loading响应    store.dispatch('CancalLoading');    ...})

在组件内定义

<el-button :loading="btn.save" @click="handleClick">保存</el-button>computed: {    btn() {        return this.$store.state.loading;    }}methods: {    handleClick() {        this.$store.dispatch('SetLoading', { save: true });        }}

以上就可以完美的使用loading,而不用每个都在data中定义了。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

(0)
上一篇 2022年10月2日 上午9:06
下一篇 2022年10月2日 上午9:19

相关推荐

  • 如何开发微信小程序公众号(如何开发微信小程序公众号)

    随着时间的流逝,随着互联网的飞速发展,微信越来越成为我们生活中的一部分,微信小程序公众号也成为了许多公司的标配,与此同时,许多公司也趁机抓住机会,成为了第三方开发公司,但价格却各不…

    科研百科 2023年4月4日
    154
  • 纵向科研项目申报书范例

    纵向科研项目申报书范例 项目名称:XXX 科技创新项目 项目简介: 该项目旨在解决XXX 领域中存在的技术难题,提升该领域的技术水平。该项目属于XXX 领域,主要研究XXX。该项目…

    科研百科 2025年4月22日
    2
  • 中组部印发《关于进一步发挥全国党建研究会党建高端智库作用的意见》

    本报北京讯(特约记者仲组轩)为贯彻落实习近平总书记关于全国党建研究会要“发挥党建高端智库作用”的重要指示精神,近日,中共中央组织部印发《关于进一步发挥全国党建研究会党建高端智库作用…

    科研百科 2024年6月22日
    33
  • 工程项目管理软件对施工企业有什么价值?(工程项目管理软件有哪些价值)

    近年来,数据化已经渗入到企业管理的方方面面,建设工程企业也正在迎来一场数据化管理变革。目前,为了实现数字化转型,很多企业开始引入数字化工程项目管理系统,对企业内部以及各个项目进行标…

    科研百科 2022年7月24日
    153
  • 横向科研项目代购设备

    标题:横向科研项目代购设备 随着科技的不断发展,横向科研项目已经成为现代科学研究中不可或缺的一部分。在这些项目中,研究人员需要购买各种设备来帮助他们进行实验和研究。然而,由于横向科…

    科研百科 2025年3月22日
    3
  • 海南省就业补贴政策

    海南省就业补贴政策 近年来,海南省经济发展迅速,就业市场也呈现出繁荣景象。为了促进就业,海南省政府制定了一系列的就业补贴政策,以支持企业和员工就业。本文将介绍海南省就业补贴政策的主…

    科研百科 2024年10月29日
    2
  • 1999年,倪光南院士被联想扫地出门,如今82岁的他从未放弃(倪光南院士被联想开除)

    1 提起“倪光南”这个名字,可能现在的很多年轻人并不熟悉,但是对于“柳传志”这个名字,大家再熟悉不过了。 柳传志用了二十年的时间,将“联想”从一个一穷二白的小公司做成了全球知名的电…

    科研百科 2024年4月5日
    93
  • 电子档案管理系统平台

    电子档案管理系统平台 随着科技的不断发展,电子档案管理系统平台已经成为了档案管理领域中不可或缺的一部分。电子档案管理系统平台不仅可以提高档案管理的效率和准确性,还可以让档案管理更加…

    科研百科 2024年9月25日
    22
  • 佛山抗疫科研项目

    佛山抗疫科研项目:用科技手段帮助患者快速康复 2020年,新冠疫情在全球范围内肆虐,给人们的生活和经济带来了极大的影响。在这场没有硝烟的战争中,中国人民展现了非凡的团结和坚韧,成为…

    科研百科 2025年2月22日
    2
  • 生理学研究性学习课题

    生理学研究性学习课题 性学习是儿童成长过程中非常重要的一个方面。通过性学习,孩子们可以了解自己的身体,认识自己的身体特征,并且掌握一些健康的性知识和性技巧。然而,性学习的质量和效果…

    科研百科 2024年11月14日
    1