Vue3表单提交后部门名称不更新,需手动刷新页面
Vue3表单更新后部门名称无法实时显示的问题
问题描述
在Vue3项目的排班调度器列表组件中,提交更新表单后,排班的其他数据能正常刷新显示,但关联的部门名称不会同步更新,必须手动刷新页面才能看到最新的部门名称。
代码片段
数据获取与映射
onBeforeMount(async () => { try { isLoadingShiftSchedular.value = true; isLoadingDepartments.value = true; const getDepartment = await useApiFetch('/api/departments'); if (!getDepartment.error.value) { departmentList.value = getDepartment.data.value.data; departmentMap.clear(); departmentList.value.forEach(department => { departmentMap.set(department.user_departmentID, department.department_name); }); const getShiftSchedular = await useApiFetch('/api/shiftschedular'); if (!getShiftSchedular.error.value) { shiftSchedularList.value = getShiftSchedular.data.value.data; shiftSchedularList.value = shiftSchedularList.value.map(shift => ({ ...shift, user_department_name: departmentMap.get(shift.user_departmentID) || 'Department name not found' })); } } } catch (error) { console.error('Error fetching data:', error); } finally { isLoadingShiftSchedular.value = false; isLoadingDepartments.value = false; } });
表单更新逻辑
const handleUpdate = async () => { isUpdateDialogVisible.value = false; isLoadingVisible.value = true; await useApiFetch("/sanctum/csrf-cookie"); const payload = { ...form.value, status: form.value.status === 'Active' }; const { data, error } = await useApiFetch("/api/shiftschedular/" + form.value.shift_schedularID, { method: "PATCH", body: payload }); if (!error.value) { const getShiftSchedular = await useApiFetch("/api/shiftschedular"); shiftSchedularList.value = getShiftSchedular.data.value.data; form.value = {}; isLoadingVisible.value = false; successAlertMessage.value = data.value.message || 'Update successful!'; successAlertVisible.value = true; } else { isLoadingVisible.value = false; errorAlertVisible.value = true; errorAlertMessage.value = error.value.message || 'An error occurred.'; } };
模板绑定
<template #item.user_department="{ item }"> <span> {{ item.user_department_name }} </span> </template>
表单更新弹窗
<!-- Update Form Dialog --> <VDialog v-model="isUpdateDialogVisible" persistent width="1100"> <DialogCloseBtn @click="isUpdateDialogVisible = !isUpdateDialogVisible" /> <VCard title="Update Shift Scheduler"> <VCardText v-if="isLoadingUpdateVisible"> <VSkeletonLoader class="mx-auto" type="text, actions" /> </VCardText> <VCardText v-if="!isLoadingUpdateVisible"> <VRow> <VCol cols="12" md="8"> <VRow> <VCol cols="12"> <VSwitch v-model="form.status" :label="form.status" true-value="Active" false-value="Inactive" /> </VCol> <VCol cols="12"> <AppTextField v-model="form.name" label="Name" /> </VCol> <VCol cols="12"> <AppDateTimePicker v-model="form.shift_start" label="Shift Start" placeholder="Time" :config="{ enableTime: true, noCalendar: true, dateFormat: 'H:i' }" /> </VCol> <VCol cols="12"> <AppDateTimePicker v-model="form.shift_end" label="Shift End" placeholder="Time" :config="{ enableTime: true, noCalendar: true, dateFormat: 'H:i' }" /> </VCol> <VCol cols="12"> <AppSelect v-model="form.user_departmentID" :items="departmentList" label="Department" placeholder="Select Department" /> </VCol> </VRow> </VCol> <VCol cols="12" md="4"> <VCard class="pa-3" outlined> <!-- Label for Color Picker --> <div class="mb-2"> <span class="font-weight-medium">Select Department Color</span> </div> <v-color-picker label="Chips" v-model="form.color" elevation="15" /> </VCard> </VCol> </VRow> </VCardText> <VCardText v-if="!isLoadingUpdateVisible" class="d-flex justify-end flex-wrap gap-3"> <VBtn variant="tonal" color="secondary" @click="isUpdateDialogVisible = false"> Close </VBtn> <VBtn :disabled="isLoadingVisible" @click="handleUpdate"> Save </VBtn> </VCardText> </VCard> </VDialog>
预期与实际行为
- 预期行为:更新排班调度器后,部门名称无需刷新页面即可实时显示
- 实际行为:部门名称必须手动刷新页面才会更新显示
已尝试操作
- 确认初始化时部门名称已正确获取并映射到
departmentMap - 验证更新后拉取的
shiftSchedularList包含正确的部门ID,但UI未自动更新名称
解决方案
问题核心:更新后重新拉取的排班数据仅包含部门ID,没有像初始化时那样生成user_department_name字段,而UI绑定的正是这个字段,因此无法显示最新名称。
修改handleUpdate函数,在更新排班列表时重复初始化时的映射逻辑:
const handleUpdate = async () => { isUpdateDialogVisible.value = false; isLoadingVisible.value = true; await useApiFetch("/sanctum/csrf-cookie"); const payload = { ...form.value, status: form.value.status === 'Active' }; const { data, error } = await useApiFetch("/api/shiftschedular/" + form.value.shift_schedularID, { method: "PATCH", body: payload }); if (!error.value) { const getShiftSchedular = await useApiFetch("/api/shiftschedular"); // 关键修改:给新拉取的排班数据添加user_department_name字段 shiftSchedularList.value = getShiftSchedular.data.value.data.map(shift => ({ ...shift, user_department_name: departmentMap.get(shift.user_departmentID) || 'Department name not found' })); form.value = {}; isLoadingVisible.value = false; successAlertMessage.value = data.value.message || 'Update successful!'; successAlertVisible.value = true; } else { isLoadingVisible.value = false; errorAlertVisible.value = true; errorAlertMessage.value = error.value.message || 'An error occurred.'; } };
原因说明
初始化阶段我们通过departmentMap将部门ID转换为名称,并给每个排班项添加了user_department_name字段。但更新时直接使用后端返回的原始数据,这些数据没有该字段,UI自然无法更新。添加映射逻辑后,新的排班数据会带上对应部门名称,无需刷新页面就能正常显示。
内容的提问来源于stack exchange,提问作者Dirk Robbertse
相关产品推荐
相关产品推荐

