Fix Bug #548: isInitializing 同步赋值但 Vue watcher 异步执行导致拦截失效 — transferValue 赋值后加 await nextTick() 确保 watcher 在标志为 true 时执行

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-19 09:05:09 +08:00
parent d4f67a994a
commit 45dbacb0bf
2 changed files with 33 additions and 3 deletions

View File

@@ -33,3 +33,30 @@
2. `transferValue` 的 watch 增加 `if (isInitializing.value) return;` 拦截
3. `applyEditTransferSelection()` 中设置 `transferValue` 前后加 `isInitializing` 标志
4. `applicationListAll` 的 watch 中设置 `transferValue` 前后也加 `isInitializing` 标志
## 二次修复isInitializing 时序问题)
### 二次根因
Vue 的 `watch()` 回调默认是**异步刷新**的(在下一个 microtask 执行)。前一轮修复使用了同步模式:
```js
isInitializing.value = true
transferValue.value = uniq // watcher 被排队,尚未执行
isInitializing.value = false // 在 watcher 回调执行前已重置
// → watcher 触发时 isInitializing 已为 false → 拦截失效
```
导致 `projectWithDepartment(newValue, 1)` 仍然被调用,`form.targetDepartment = ''` 仍然清空了 descJson 中的科室值。
### 修复方案
`applyEditTransferSelection``applicationListAll` watch 中,设置 `transferValue` 后使用 `await nextTick()` 确保 Vue 的 watcher 在 `isInitializing``true` 的状态下执行完毕,然后再重置为 `false`
### 修复结果:✅ 成功5行改动
**改动文件**: `openhis-ui-vue3/src/views/inpatientDoctor/home/components/order/applicationForm/laboratoryTests.vue`
1. import 增加 `nextTick`
2. `applyEditTransferSelection` 改为 `async` 函数,`transferValue` 赋值后加 `await nextTick()`
3. `applicationListAll` 的 watch 回调改为 `async``transferValue` 赋值后加 `await nextTick()`

View File

@@ -134,7 +134,7 @@
</div>
</template>
<script setup name="LaboratoryTests">
import {getCurrentInstance, onMounted, reactive, ref, watch, computed} from 'vue';
import {getCurrentInstance, nextTick, onMounted, reactive, ref, watch, computed} from 'vue';
import {patientInfo} from '../../../store/patient.js';
import {getApplicationList, saveInspection} from './api';
import {getOrgList} from '@/views/doctorstation/components/api.js';
@@ -349,7 +349,7 @@ watch(
);
/** 编辑弹窗:根据申请单明细把右侧「已选择」与 transferValue 对齐(依赖 applicationListAll 已加载) */
const applyEditTransferSelection = () => {
const applyEditTransferSelection = async () => {
const newData = props.editData
if (!newData?.requestFormId || !newData.requestFormDetailList?.length) {
return
@@ -383,6 +383,8 @@ const applyEditTransferSelection = () => {
// 设置初始化标志,防止 transferValue 变化触发 projectWithDepartment 覆盖 descJson 中的科室值
isInitializing.value = true
transferValue.value = uniq
// Vue watcher 默认异步刷新,必须 await nextTick 确保 watcher 在 isInitializing 为 true 时执行
await nextTick()
isInitializing.value = false
if (newData.requestFormDetailList.length && uniq.length === 0) {
console.warn(
@@ -419,7 +421,7 @@ watch(
// 编辑模式下applicationListAll 加载完成后重新回显已选项目
watch(
() => applicationListAll.value,
() => {
async () => {
if (!props.editData?.requestFormId) return;
if (!props.editData.requestFormDetailList?.length) return;
if (!applicationListAll.value.length) return;
@@ -435,6 +437,7 @@ watch(
});
isInitializing.value = true;
transferValue.value = selectedIds;
await nextTick();
isInitializing.value = false;
}
);