Vue.js 生态系统深度探索与项目实战:一个医疗软件Python开发的“叛逃”手记
上周五晚上十点,我正坐在成都家中阳台上,一边吸着老妈做的红油抄手,一边用 Vim 打开一个刚 fork 的前端仓库。说来你可能不信——我这个写了八年 Python、连 FastAPI 装饰器都能闭眼写的后端老狗,居然在认真研究 Vue 3 的 Composition API。
这事得从去年双11说起。我们公司(一家专注医疗信息化的中型软件企业)接了个新项目:为某三甲医院开发一套全新的患者随访管理系统。UI 部分原本是外包给一个 React 团队做的,结果临近交付前两周,对方团队突然“跑路”——说是主力工程师跳槽去了字节。产品经理小李急得在 Slack 上@我:“老张,你不是会写点 HTML 吗?能不能救个火?”
我:???
我会写 HTML 是因为二十年前用 Dreamweaver 做过个人主页,跟现代前端框架能是一回事吗?但架不住领导画饼+周末加班补贴翻倍,硬着头皮接了下来。于是,我这个 Vim 党,在 PyCharm 都很少打开的人,被迫踏进了 Vue.js 的世界。
为什么选 Vue?而不是继续“舔”React?
说实话,最初我是想直接上 React 的。毕竟 React 在医疗行业里也不少见,而且我们后端用的是 Django + DRF,理论上前后端分离架构下前端框架随便换。但现实很快打了我的脸:
- 学习曲线:React Hooks 虽然强大,但对一个习惯了同步逻辑、讨厌状态管理爆炸的 Python 程序员来说,useEffect 里套 useReducer 再套 useContext 的嵌套地狱让我一度想回老家种菜。
- 团队现状:我们公司前端就俩人,一个还在学 TypeScript,另一个主攻小程序。React 生态虽大,但上手成本高,文档又“抽象”。Vue 的选项式 API(Options API)一眼看过去就像配置文件,特别适合我们这种“非专业前端”快速上手。
- 国内生态友好:尤雨溪是华人,中文文档质量吊打大部分开源项目。Element Plus、Naive UI 这些组件库对国内医疗系统的表单、表格、弹窗需求支持得贼到位——要知道,医生填个随访表单动不动就是 50+ 字段,还要求实时校验、动态联动。
尤其是上次上线时,测试同事报了个 bug:“点击‘保存’按钮没反应。”
我一查控制台,好家伙:TypeError: Cannot read property 'map' of undefined。
在 React 里我可能要翻半天 Redux 状态树,但在 Vue 里,直接看data()返回的对象结构,五分钟定位到后端返回的followupItems字段偶尔是 null 而不是空数组。改一行代码搞定。那一刻,我真的觉得 Vue 对“非前端思维”太友好了。
从零搭建:一个医疗随访系统的 Vue 实战
我们的系统核心功能其实不复杂:医生创建随访计划 → 患者通过小程序接收任务 → 后台管理端查看完成情况。但难点在于交互密集、数据联动强、权限粒度细。
技术栈选择(2024年版)
| 类别 | 选择 | 原因 |
|---|---|---|
| 核心框架 | Vue 3 (Composition API) | 更好的 TypeScript 支持,逻辑复用更灵活 |
| 状态管理 | Pinia | 比 Vuex 简洁太多,模块化天然支持,和 Composition API 天生一对 |
| UI 组件库 | Naive UI | 设计清爽,TypeScript 友好,暗色模式支持(医生夜班用!) |
| HTTP 客户端 | Axios + 自定义拦截器 | 统一处理 token 刷新、错误提示 |
| 构建工具 | Vite | 启动快如闪电,热更新秒级响应 —— 再也不用等 Webpack 编译等到睡着了 |
关键场景:动态表单 + 实时校验
医疗表单最头疼的就是“动态字段”。比如某个随访项如果选了“有并发症”,就要展开一堆子问题。传统做法是 v-if 控制显示,但字段多起来,data 里全是布尔值开关,维护起来像蜘蛛网。
后来我用了 ref + reactive 组合:
// composables/useFollowupForm.ts
import { ref, reactive } from 'vue'
export function useFollowupForm() {
const form = reactive({
hasComplication: false,
complicationDetails: [] as string[],
bloodPressure: null,
// ...其他字段
})
const rules = computed(() => ({
bloodPressure: [
{ required: true, message: '请输入血压值' },
{ validator: validateBP, trigger: 'blur' }
],
complicationDetails: form.hasComplication
? [{ required: true, message: '请填写并发症详情', type: 'array' }]
: []
}))
return { form, rules }
}
在组件里直接解构使用:
<script setup>
import { useFollowupForm } from '@/composables/useFollowupForm'
const { form, rules } = useFollowupForm()
</script>
<template>
<n-form :model="form" :rules="rules">
<n-form-item label="是否有并发症" path="hasComplication">
<n-switch v-model:value="form.hasComplication" />
</n-form-item>
<n-form-item v-if="form.hasComplication" label="并发症详情" path="complicationDetails">
<n-dynamic-tags v-model:value="form.complicationDetails" />
</n-form-item>
</n-form>
</template>
这套方案让表单逻辑从模板里剥离出来,测试也好写多了。最关键的是——再也不用在 template 里写三元表达式判断校验规则了!之前看 React 项目里那些 condition ? [rule1, rule2] : [rule3],真的头大。
和 React 的“综合”对比:不是对立,而是互补
我知道肯定有 React 死忠粉要喷:“这不就是把 useState 拆出来封装嘛?” 你说得对,但工程效率不只看技术上限,更看团队认知成本。
我们后端团队 6 个人,4 个会 Python,2 个会 Java,没人专职前端。Vue 的文档就像一本写给工程师看的说明书,而 React 文档有时候读起来像哲学论文(Looking at you, Concurrent Mode)。
不过我也承认,React 在大型应用的状态管理、跨平台(RN)上有优势。所以现在我们内部有个“综合策略”:
- 管理后台、数据密集型页面 → 用 Vue(开发快、调试直观)
- 患者端 H5 / 小程序 → 用 Taro + React(一套代码多端运行)
- AI 辅助诊断模块的可视化 → 用 D3 + 原生 JS(性能优先)
说白了,别被框架绑架。就像我最近在啃的《代码人生》这本书里说的:“工具是仆人,不是主人。” (虽然这本书其实是讲算法的,但这句话被我强行挪用来安慰自己转前端的焦虑)
性能优化:别让医生等得想砸键盘
医疗系统最怕卡顿。医生一天要看上百个患者,如果点个按钮要等两秒,他们真的会打电话骂运维。
我们做了几件事:
路由懒加载:
// router/index.ts const FollowupList = () => import('@/views/followup/List.vue')首屏加载时间从 3.2s 降到 1.1s。
虚拟滚动:患者列表经常上千条,用
vue-virtual-scroller后内存占用降了 70%。防抖搜索:医生输患者姓名时,用
lodash.debounce避免疯狂请求后端。生产构建分析:
vite build --report发现 Element Plus 全量引入占了 1.8MB!立刻改成按需引入:
// vite.config.ts import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import AutoImport from 'unplugin-auto-import/vite' import Components from 'unplugin-vue-components/vite' import { NaiveUiResolver } from 'unplugin-vue-components/resolvers' export default defineConfig({ plugins: [ vue(), AutoImport({ imports: ['vue'] }), Components({ resolvers: [NaiveUiResolver()] }) ] })
上线后 Lighthouse 分数从 68 提到 92,运维小哥终于不用半夜被 PagerDuty 叫醒了。
调试技巧:Vim 党的前端生存指南
作为一个拒绝 VS Code 的 Vim 党,我摸索出一套“极简前端调试法”:
- 浏览器 DevTools +
console.log:别笑,真香。Vue 3 的<script setup>里变量可以直接在 console 里访问(配合expose)。 - Vue Devtools 插件:必须装!能直接看组件树、Pinia 状态、事件流。比 React Devtools 更直观(个人观点)。
- Vite 的 HMR 日志:热更新失败时,终端会明确告诉你哪个模块没更新成功,不用瞎猜。
- 用
v-memo优化列表:当列表项有复杂计算时,加上这个指令能避免无效重渲染。
最骚的操作是我把 .vimrc 配了自动补全 Vue 模板语法:
autocmd FileType vue setlocal omnifunc=vsnip#complete
虽然比不上 IDE,但至少 <template> 里敲 div. 能自动补成 <div class=""></div> —— 老程序员的倔强罢了。
写在最后:代码人生,不止一种活法
现在回头看,从被逼上梁山到主动拥抱 Vue,这段经历让我意识到:所谓“全栈”,不是什么都会,而是知道什么时候该用什么工具解决问题。
上周产品又提了个需求:“能不能加个 AI 自动生成随访建议的功能?” 我一边在 Jupyter Notebook 里跑 BERT 模型,一边在 Vue 组件里调用后端接口展示结果。那一刻,Python 和 Vue 的代码在我屏幕上交相辉映,突然觉得——这不就是《代码人生》里描绘的理想状态吗?技术没有高低贵贱,只有是否合适。
当然,如果产品经理再敢让我改 UI 配色(上次非要从蓝色改成“医患和谐绿”),我可能真的会提离职去卖火锅底料。毕竟在成都,生活节奏舒服,但底线不能丢啊。
P.S. 如果你也是后端转前端的苦命人,推荐两本书:
- 《Vue.js 设计与实现》——霍春阳写的,深入浅出,讲透响应式原理
- 《代码人生》——虽然书名鸡汤,但第 7 章讲“技术选型的心理陷阱”简直是我的嘴替
共勉。

评论 0