Vue3 前端架构重构实践:从双端分离到统一响应式组件
引言
本文将介绍我们基于 Vue3 + TypeScript 的前端项目重构过程,通过渐进式的系统性重构,我们将原本分离的桌面端、移动端两套代码,整合为了一套统一的响应式组件架构,大幅提升了代码可维护性与开发效率。
重构背景
在重构之前,我们的项目采用了传统的双端分离架构:桌面端和移动端拥有完全独立的组件,比如桌面端的Home.vue对应移动端的MobileHome.vue,桌面端的Device.vue对应移动端的MobileDevice.vue,以此类推。
这种架构在项目初期可以快速迭代,但是随着项目的迭代,逐渐暴露了很多问题:
-
代码严重重复:相同的业务逻辑需要在两个组件中分别实现,大量重复代码
-
维护成本极高:修复 Bug 或者添加新功能,需要同时修改双端的代码,很容易遗漏
-
体验一致性差:双端的界面风格、交互行为很难保持完全一致
-
开发效率低下:每开发一个新功能,都需要编写两套代码,工作量翻倍
为了解决这些问题,我们启动了这次架构重构,目标是将双端代码整合为一套统一的响应式组件,实现一套代码、双端适配。
渐进式重构阶段
我们没有选择一次性的重写,而是采用了渐进式的重构策略,分阶段完成,每个阶段都保证系统可正常运行,逐步完成整个架构的升级:
阶段一:统一 API 层基础设施
重构的第一步,我们先统一了底层的 API 基础设施,这是后续所有组件整合的基础:
import { ElMessage } from 'element-plus';import router from '@/router';const BASE_URL = '';
// 统一请求拦截器:自动添加Token、处理请求头const requestInterceptor = (config: RequestInit) => { const token = localStorage.getItem('accessToken'); const headers = new Headers(config.headers);
if (token) { headers.set('Authorization', `Bearer ${token}`); } headers.set('Accept', 'application/json');
return { ...config, headers, credentials: 'include' };};
// 统一响应拦截器:自动处理401、错误提示const responseInterceptor = async (response: Response) => { if (response.status === 401) { // 登录过期处理 localStorage.clear(); window.dispatchEvent(new Event('loginStatusChanged')); ElMessage.error('登录已过期,请重新登录'); router.push('/Login'); throw new Error('Unauthorized'); }
if (!response.ok) { const error = await response.json().catch(() => ({})); throw new Error(error.detail || error.msg || '请求失败'); }
return response.json();};
// 统一请求方法export const api = { async get<T = any>(url: string, params?: Record<string, any>): Promise<T> { // ... GET请求实现,自动拼接参数 }, async post<T = any>(url: string, data?: any): Promise<T> { // ... POST请求实现,自动序列化数据 }, // ... put、delete等其他请求方法};这一步我们修改了 14 个文件,移除了所有组件中重复的 fetch 调用,统一替换为这个 api 方法,总共减少了 850 行重复的网络请求代码,同时统一了错误处理、Token 管理的逻辑。
阶段二:组件整合,从总览页面开始
完成了 API 层的统一后,我们开始逐步整合双端的组件,首先从最简单的总览页面开始:
我们将原来的Home.vue和MobileHome.vue整合为了一个统一的HomePage.vue,核心的逻辑是通过设备检测,实现不同布局的条件渲染:
<template> <div :class="['home-container', { 'mobile': isMobile }]"> <!-- 桌面端布局 --> <div v-if="!isMobile" class="desktop-layout"> <!-- 桌面端的多列网格布局 --> </div> <!-- 移动端布局 --> <div v-else class="mobile-layout"> <!-- 移动端的单列堆叠布局 --> </div> </div></template><script setup>import { computed } from 'vue';// 核心的设备检测逻辑const isMobile = computed(() => { return window.innerWidth < 768 || /Android|iPhone|iPad/i.test(navigator.userAgent);});</script>这一步我们删除了无用的旧组件,将 6 个文件精简为 5 个,减少了 1274 行重复代码,同时实现了真正的响应式布局。
阶段三:复杂组件的适配
完成了简单组件的整合后,我们开始处理复杂的业务组件,比如设备管理界面、数据管理界面: 这些组件的功能比较复杂,桌面端使用表格展示,移动端使用卡片列表,同时数据展示的粒度也有差异,我们的解决方案是:核心业务逻辑完全统一,仅 UI 层做差异化适配:
<template> <div class="device-page"> <!-- 桌面端:表格视图,适合大屏操作 --> <el-table v-if="!isMobile" :data="devices"> <!-- 表格列定义,支持批量操作、编辑等 --> </el-table>
<!-- 移动端:卡片列表,适配小屏触摸操作 --> <div v-else class="mobile-device-list"> <div v-for="device in devices" :key="device.id" class="device-card"> <!-- 卡片化的设备信息展示 --> </div> </div> </div></template>针对数据管理这类有图表的页面,我们还做了数据的差异化优化:移动端自动对图表数据做采样,避免小屏上数据过于拥挤:
// 桌面端显示24小时数据,移动端显示6小时,同时自动采样const chartData = computed(() => { const data = rawData.value; if (isMobile.value && data.length > 12) { // 移动端采样为12个点,优化显示 const step = Math.ceil(data.length / 12); return data.filter((_, index) => index % step === 0); } return data;});阶段四:全量组件适配
完成了核心业务组件的整合后,我们用同样的逻辑,逐步完成了所有页面的适配:
-
登录、注册界面:整合了双端的表单,适配不同屏幕的输入尺寸
-
个人信息界面:统一了表单布局,桌面端水平排列,移动端垂直堆叠
-
用户管理界面:统一了权限控制,双端的管理逻辑完全一致
-
备案等基础组件:也同步完成了整合,删除了独立的移动端组件
整个过程我们都是渐进式的,每完成一个组件的整合,就进行测试,保证功能的完整性,避免重构带来的 regression。
重构的最终成果
代码量的变化
整个重构过程,我们总共减少了约 4415 行重复代码,各阶段的变化如下:
| 重构阶段 | 修改文件数 | 代码精简量 |
|---|---|---|
| API 层重构 | 14 | -850 行 |
| 总览组件整合 | 6 | -1274 行 |
| 设备界面整合 | 5 | -389 行 |
| 登录 / 注册 / 个人信息 | 13 | -738 行 |
| 用户管理整合 | 3 | -631 行 |
| 数据管理整合 | 3 | -513 行 |
| 备案信息整合 | 8 | -20 行 |
架构收益
这次重构完成后,我们的架构得到了显著的优化:
-
维护性大幅提升:相同功能只需要维护一份代码,修复 Bug、添加功能只需要修改一次
-
体验一致性:双端的界面风格、交互行为完全一致,不会出现双端功能不一致的问题
-
开发效率翻倍:新功能的开发工作量减少了 50%,不需要再编写两套代码
-
性能优化:移除了大量的重复代码,减少了包体积与运行时的资源消耗
实现中的挑战与解决方案
在重构过程中,我们也遇到了一些挑战,对应的解决方案如下:
-
功能差异适配:针对双端的功能差异,我们通过计算属性动态配置,核心业务逻辑完全统一,仅 UI 层做差异化
-
移动端性能优化:针对移动端的性能限制,我们实现了数据采样、懒加载,优化了移动端的渲染性能
-
样式冲突处理:我们通过平台特定的类名、BEM 命名规范、CSS 模块化,避免了双端样式的冲突
总结
通过这次渐进式的系统性重构,我们成功将一个双端分离的老旧架构,升级为了现代化的统一响应式架构,解决了原来的维护成本高、开发效率低的问题。
这次重构的关键经验是:
-
先统一基础设施:API 层、工具层的统一,是后续组件整合的基础
-
渐进式重构:分阶段、逐个组件的重构,保证每个阶段系统都可用,降低重构风险
-
逻辑与 UI 分离:核心业务逻辑完全统一,仅 UI 层做差异化适配,最大化代码复用
如果你也在维护一个双端分离的老旧项目,不妨参考这套渐进式重构的方案,它可以帮助你平稳的完成架构升级,同时大幅提升开发效率。
部分信息可能已经过时









