# testProjectConfiguration 页面性能改造操作手册 **适用范围**:前端 beiHai-ui / 后端 beiHai-lims **改造目标**:页面打开 20 秒 → 2~3 秒以内 **说明**:本手册只写「怎么改」,每个改动都给出文件路径、行号、改前/改后代码。按编号顺序执行即可,做完 1~3 步就能砍掉绝大部分耗时。 --- ## 📋 改动清单总览 | 步骤 | 改动 | 收益 | 风险 | |---|---|---|---| | 1 | 3 个弹窗子组件懒加载(v-if) | 砍掉约 14 个首屏请求(最大收益) | 中(需同步改子组件 watch) | | 2 | 删除死代码 `gettestItemNameTypeList` | 少 1 个全量请求 | 极低 | | 3 | `getList()` 改为打开弹窗时才调用 | 首屏少 1 个 500 条请求 | 极低 | | 4 | 勾选/点击行加防抖 | 避免子表请求风暴 | 低 | | 5 | 子表 pageSize 990 → 50 | 减少每次交互的数据量 | 低 | | 6 | 表格瘦身(去 sortable/show-summary) | 减少渲染开销 | 低(视觉略有变化) | | 7 | 后端补索引(必须做) | 生产库数据量大时兜底 | 低(上线前 DBA 评估) | | 8 | 后端字典查询 pageSize 调小 | 减少全量传输 | 低 | | 9 | 后端关闭 SQL 日志输出 | 减少日志 IO | 极低 | > ⚠️ **先备份再动手**:每个文件修改前先复制一份,例如 `testProjectConfiguration.vue.bak`。改完用 `npm run dev` 起本地验证。 --- ## 第 1 步:3 个弹窗子组件懒加载(核心改动,必须做) 弹窗子组件 `alertComponents / alertComponents3 / alertComponents4` 目前**页面一打开就被实例化**,各自 `mounted` 里发 5~7 个请求。改成「第一次打开弹窗时才创建组件」。 ### 1.1 父组件加 v-if **文件**:`src/views/standardManagement/components/testProjectConfiguration/testProjectConfiguration.vue` **位置**:第 320~323 行 **改前**: ```html
``` **改后**: ```html ``` ### 1.2 三个子组件 watch 加 immediate(⚠️ 必须同步改,否则弹窗打不开) **原因**:子组件通过 `watch: { showFlag }` 打开弹窗。加 v-if 后,组件首次创建时 `showFlag` 已经是 `true`,**watch 默认不触发首次值**,弹窗会打不开。必须加 `immediate: true`。 **文件 1**:`src/views/standardManagement/components/testProjectConfiguration/alertComponents.vue` **位置**:第 456~459 行 **改前**: ```js watch: { showFlag (arg) { this.dialogTableVisible = true; } }, ``` **改后**: ```js watch: { showFlag: { handler (arg) { this.dialogTableVisible = true; }, immediate: true } }, ``` **文件 2**:`alertComponents3.vue`,第 412~416 行 —— 同样改法(结构一致,照上面抄)。 **文件 3**:`alertComponents4.vue`,第 171~189 行 —— 同样改法(注意它 watch 里可能还有别的逻辑,只把 `showFlag` 这个 handler 包成对象 + `immediate: true`)。 ### 1.3 验证 ``` npm run dev ``` 1. 打开测试项目配置页 → 打开浏览器 DevTools Network,刷新页面 2. 观察首屏请求数量:应从 ~19 个降到 ~4 个(只剩父组件的字典 + 主表分页 + 3 个 addScreen) 3. 点击「新增」按钮 → 弹窗应正常打开,此时才出现弹窗的字典请求(正常现象) 4. 连续开/关弹窗 2~3 次,确认不报错 --- ## 第 2 步:删除死代码 gettestItemNameTypeList 该请求拉取全部测试项目,结果存入 `testItemNameType`,但**模板里从未使用**(页面下拉用的是 `itemTypeNameType`,来自另一个接口)。纯浪费。 **文件**:`testProjectConfiguration.vue` **改动 2.1**:删掉第 422 行的调用 ```js this.gettestItemNameTypeList(); // ← 删除这一行 ``` **改动 2.2**:删掉第 430~435 行的方法定义 ```js gettestItemNameTypeList () { this.axios.get('pass/baseManagement/v1/limsstdtestitems/'+ '?validFlag=1') .then(res => { this.testItemNameType = res.data.list; }) }, ``` (可一并删掉 data 里第 395 行的 `testItemNameType: []`,不删也无害) --- ## 第 3 步:getList() 改为弹窗打开时才调用 `getList()` 查询分析项目(pageSize=500),数据只在「新增分析项目」弹窗里用,但目前页面一打开就拉。 **文件**:`testProjectConfiguration.vue` **改动 3.1**:删掉第 418 行的 mounted 调用 ```js this.getList() // ← 删除这一行 ``` **改动 3.2**:在 `addData2()`(第 626~633 行)里补上调用 **改前**: ```js addData2 () { let _this = this; if (_this.multipleSelection.length !== 1) { this.$message.warning('请选择一条测试项目数据!'); return } this.dialogTableVisible = true }, ``` **改后**: ```js addData2 () { let _this = this; if (_this.multipleSelection.length !== 1) { this.$message.warning('请选择一条测试项目数据!'); return } this.getList(); // ← 新增:弹窗打开时才加载分析项目列表 this.dialogTableVisible = true }, ``` --- ## 第 4 步:勾选/点击行加防抖(可选但建议) 当前点击/勾选任意一行,立刻触发 2 个 pageSize=990 的子表查询;多选时连续触发。 **文件**:`testProjectConfiguration.vue` **位置**:第 799~807 行(handleSelectionChange)、第 846~858 行(handleCurrentChange) **改法**:把两个方法里的 `getDataList2/getDataList3` 调用替换为防抖调用,并新增一个防抖方法。 `handleSelectionChange` 改后: ```js handleSelectionChange (val) { this.multipleSelection = val; if (val.length > 0) { this.testItemNo = val[val.length-1].testItemNo this.curItemTypeCode = val[val.length-1].itemTypeCode; this.debounceLoadSub(this.testItemNo); } }, ``` `handleCurrentChange` 改后(顺手修复 val 为 null 时的报错): ```js handleCurrentChange (val) { this.curItemTypeCode = '' if (val){ this.curItemTypeCode = val.itemTypeCode; } if (!val || val.testItemNo === null) { this.testItemNo = ''; } else { this.testItemNo = val.testItemNo; } this.debounceLoadSub(this.testItemNo); }, ``` 在 methods 里新增防抖方法(放在 getDataList2 前面即可): ```js debounceLoadSub (testItemNo) { clearTimeout(this._subTimer); this._subTimer = setTimeout(() => { this.getDataList2(testItemNo); this.getDataList3(testItemNo); }, 300); }, ``` --- ## 第 5 步:子表 pageSize 990 → 50,恢复分页 **文件**:`testProjectConfiguration.vue` **位置**:第 370~379 行 **改前**: ```js page2: { pageSize: 990, pageNum: 1, totalPage: 0 }, page3: { pageSize: 990, pageNum: 1, totalPage: 0 }, ``` **改后**: ```js page2: { pageSize: 50, pageNum: 1, totalPage: 0 }, page3: { pageSize: 50, pageNum: 1, totalPage: 0 }, ``` **建议同时恢复被注释的分页组件**:第 136~141 行有被注释的 `