You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 22:22:04