vue 项目代码拆分的方案

作者:Chieffo 时间:2024-06-05 09:17:56 

目录
  • 背景

  • 目的

  • 拆分前

    • 流程设计

    • 目录结构设计

    • 存在的问题

  • 拆分后

    • 流程设计

    • 目录结构设计

    • 解决的问题

  • 关键代码

    • 总结

      • 其他实现方式

        背景

        由于之前的数据库防火墙产品与数据库审计产品使用的是同一套代码,随着两个产品功能的差异越来越大,代码的冗余度和偶合度越来越高,为了便于后期维护以及添加新功能,所以基于原来的项目代码,进行了代码结构拆分。

        注意:本次拆分只拆分了可以拆分的部分,有的模块例如:规则、关于我们,是没有进行拆分的,一是有的模块很简单,没必要拆分;二是有的模块原先写得代码偶合太严重,无法拆分,如果要拆分,需要花费大量精力去梳理代码,同时还要后端配合拆分。

        目的

        将此次代码拆分方案记录下来,便于后来的开发人员快速熟悉项目结构。

        拆分前

        流程设计

        vue 项目代码拆分的方案

        项目拆分前,区分数审和防火墙功能的流程如上图所示。

        访问系统时,先加载入口文件 main.js,然后加载登录页 login.vue,加载登录页的同时获取产品模式并保存到 session.storage.platformType 中,接着用户登录系统进入具体页面,该页面同时包含了数审和防火墙的功能,根据 session.storage.platformType 保存的值来判断,具体显示哪个功能。

        目录结构设计

        vue 项目代码拆分的方案

        项目拆分前的目录结构如上图所示。

        该目录结构是初始化一个 Vue 项目时的基本目录,根据目录结构,基本上看不出该项目包含了两个不同的产品,也不知道不同产品模式下会加载哪一部分文件,结构不清晰。

        存在的问题

        通过分析,可以发现当前的系统流程和目录结构是存在很多问题的,大概总结下:

        1. 加载登录页的时候才获取产品模式,如果登录页加载完成,而产品模式还未获取或者获取不到,那么登录页显示的产品信息有可能是错误的;

        2. 每次进入一个具体页面,如果同时包含了数审和防火墙的功能,都要重新判断一次,当前的功能是数审的还是防火墙的;

        3. 目录结构不清晰,不清楚哪些模块是公共模块,哪些是数审独有的模块,哪些是防火墙独有的模块;

        4. 可维护性和可扩展性差。数审的代码和防火墙的代码混在一个文件内,改代码的时候需要重头看一遍才知道哪块代码属于数审,哪块代码属于防火墙。如果想要添加一个功能,还得继续加逻辑判断,代码越来越臃肿;

        5. 业务逻辑混乱,与后端通信使用了同一个接口。

        拆分后

        流程设计

        vue 项目代码拆分的方案

        项目拆分后,区分数审和防火墙功能的流程如上图所示。

        访问系统时,先加载入口文件 main.js,该文件中写了路由拦截相关的逻辑,在路由拦截时,如果没有产品模式,则要先获取产品模式,否则会被拦截,进不去系统。获取产品模式后,根据当前产品模式,会注册对应的登录页、路由配置、接口请求等。当注册完毕后,每次访问具体的页面,都应该是独立的模块了。

        目录结构设计

        vue 项目代码拆分的方案

        vue 项目代码拆分的方案

        项目拆分后的目录结构如上两个图所示。

        该目录结构经过拆分,已经可以清晰地看到不同产品之间分离出来的文件了,从入口文件开始,经过路由拦截后,会加载指定的登录页,然后把对应产品需要的文件合并到公共文件中。比如:http 请求、路由配置等。最终结果,程序只会把需要的文件加载进去。

        解决的问题

        经过重新设计,解决了当前项目存在的一些问题:

        1. 在加载登录页之前,通过路由拦截,必须先获取产品模式,才能进入系统,登录页是在获取到产品模式之后才加载的,不会出现产品信息显示错误的问题;

        2. 只有在第一次进入系统或刷新页面的时候,才会重新获取产品模式,合并产品模式对应的文件,合并的文件是拆分后的文件,不需要在文件内再次判断该有数审的功能还是防火墙的功能。

        3. 目录结构清晰,防火墙相关的功能模块文件都放在 views-fw 文件夹内。

        4. 提高了项目的可维护性和可扩展性,降低了代码的偶合度。数审的代码和防火墙的代码基本已经拆分开,如果想要添加一个防火墙的功能,只需要在防火墙相关的文件夹内新增对应功能模块的文件即可。

        5. 业务逻辑清晰,与后端通信使用的是不同的接口,公共模块使用的接口按原来的不变,数审独有的接口在 url 前面增加了 audit 前缀,防火墙独有的接口在 url 前面增加了 firewall 前缀。

        关键代码


        /**
        * @Name: main.js
        * @Author: cqfeng
        * @Description: 项目入口 js 文件
        * @MainFunction: 引入和注册一些全局资源
        **/
        //...省略的代码...
        // 路由拦截,使用全局导航守卫beforeEach
        router.beforeEach(async (to, from, next) => {
        // 如果没有产品模式,先获取产品模式
        if (!store.state.productMode.productMode) {
        await store.dispatch('productMode/SET_PRODUCT_MODE');
        }
        //...省略的代码...

        /**
        * @Name: product-mode.js
        * @Author: cqfeng
        * @Description: 产品模式相关逻辑处理文件
        * @MainFunction: 保存当前产品模式,根据不同产品模式配置 产品登录页、http 请求 等资源
        **/
        import Vue from 'vue';
        import portService from '@/assets/js/service/http/http'; // axios请求
        import router from '@/router/index'; // 默认路由配置,动态路由配置
        import httpAAS from '@/assets/js/service/http/http-aas'; // 数审独有的 http 请求
        import httpFW from '@/assets/js/service/http/http-fw'; // 防火墙独有的 http 请求
        import globalConstant from '@/assets/js/const/global-constant'; // 项目全局常量
        export default {
        namespaced: true,
        state: {
        productMode: '', // 产品模式,进入系统或刷新页面时获取
        },
        mutations: {
        // 修改产品模式
        changeProductMode: function (state, value) {
         state.productMode = value;
        },
        },
        actions: {
        async SET_PRODUCT_MODE({ commit, state }) {
         let res = await portService.getProductMode();
         if (res.data.code === 0) {
         commit('changeProductMode', res.data.data.productMode);
         }
         // 如果是数审产品
         if (state.productMode === globalConstant.COMMON.AAS) {
         // 设置产品登录页
         router.addRoutes([
          {
          path: '/login',
          name: 'login',
          component: resolve => {
           require(['@/views/login.vue'], resolve);
          },
          }
         ]);

        // 合并 http 请求,挂载到 Vue 原型上
         Vue.prototype.portService = Object.assign(portService, httpAAS);
         }
         // 如果是防火墙产品
         else if (state.productMode === globalConstant.COMMON.DBSG) {
         // 设置产品登录页
         router.addRoutes([
          {
          path: '/login',
          name: 'login',
          component: resolve => {
           require(['@/views/views-fw/login.vue'], resolve);
          },
          }
         ]);

        // 合并 http 请求,挂载到 Vue 原型上
         Vue.prototype.portService = Object.assign(portService, httpFW);
         }
        }
        }
        };

        总结

        经过拆分,数审和防火墙的代码目录已经算是基本分开了,这个过程花费的力气也很大,也引发了我的一些思考,一套代码多个项目的这种方案是否算好的方案,还有没有其他更好的方案。如果项目一开始,就按照一套代码多个项目的设计来开发,会不会后期的维护成本会低一些?这些问题我也没有答案,希望后来者能够继承历史经验,更好地开发出优秀的项目。

        其他实现方式

        起初设计拆分方案的时候,有两种方案,一种是通过获取产品模式动态改变当前产品功能,一种是在打包时通过打包参数打包指定产品包。最终的方案是选择第一种。但是,在这个过程中也参考了一些网上的实现方案,这里列出来方便以后需要用到进行参考。

        //www.aspxhome.com/article/188869.htm

        //www.aspxhome.com/article/207835.htm

        来源:https://segmentfault.com/a/1190000039416110

        标签:vue,项目,代码,拆分
        0
        投稿

        猜你喜欢

      • python递归函数用法详解

        2023-02-25 00:45:58
      • Python访问MongoDB,并且转换成Dataframe的方法

        2022-07-18 20:32:07
      • ASP读取日期单日期自动补零函数代码

        2011-02-20 10:39:00
      • PyTorch中torch.tensor与torch.Tensor的区别详解

        2023-03-07 10:48:15
      • python创建堆的方法实例讲解

        2022-11-20 05:20:49
      • centos下mysql主从复制设置详解

        2024-01-20 23:27:06
      • Go语言开发发送Get和Post请求的示例

        2024-05-21 10:23:46
      • ASP生成html的新方法

        2011-04-02 11:04:00
      • Python函数高级(命名空间、作用域、装饰器)

        2022-03-15 23:31:44
      • asp读取数据库中数据到数组的类

        2007-09-16 18:19:00
      • python Manager 之dict KeyError问题的解决

        2022-12-17 07:38:09
      • 浅谈Python NLP入门教程

        2021-04-18 14:45:53
      • MYSQL中varchar和TEXT的相关问题详析

        2024-01-23 00:58:42
      • python3.7环境下sanic-ext未生效踩坑解析

        2022-06-30 12:56:35
      • python Selenium实现付费音乐批量下载的实现方法

        2023-02-28 17:26:58
      • 怎样用JS模拟实现枚举

        2024-04-22 12:48:38
      • 学习ASP和编程的28个观点

        2008-06-27 12:57:00
      • 基于python的docx模块处理word和WPS的docx格式文件方式

        2021-11-13 12:07:55
      • MySQL多表查询与7种JOINS的实现举例

        2024-01-12 23:34:32
      • python如何实现excel数据添加到mongodb

        2023-05-05 17:23:18
      • asp之家 网络编程 m.aspxhome.com