需求:Vue3项目+Element Plus项目,点击table列表中“修改”按钮,弹窗回显该行数据。
问题:点击“修改”按钮,弹窗没有回显改行数据。
原代码展示
<template>
<div class="app-container">
<!-- 条件查询 -->
<el-form :model="queryParams" ref="queryRef" v-show="showSearch" :inline="true" label-width="68px">
<el-form-item label="Key" prop="key">
<el-input v-model="queryParams.key" placeholder="请输入cookie/token的Key" clearable style="width: 240px"
@keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="Name" prop="name">
<el-input v-model="queryParams.name" placeholder="请输入Name" clearable style="width: 240px"
@keyup.enter="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form> <!-- 表格数据 -->
<el-table v-loading="loading" :data="cookiesList" @selection-change="handleSelectionChange" ref="multipleTable">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column label="ID" prop="id" width="80" align="center" />
<el-table-column label="类型" prop="type" :show-overflow-tooltip="true" width="120" align="center" />
<el-table-column label="Name" prop="name" :show-overflow-tooltip="true" width="140" align="center" />
<el-table-column label="Key" prop="key" :show-overflow-tooltip="true" width="160" align="center" />
<el-table-column label="Value" prop="value" :show-overflow-tooltip="true" min-width="200"> <template
#default="scope"> <span class="value-text">{{ scope.row.value }}</span>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="create_time" width="200"> <template #default="scope">
<span>{{ dayjs(scope.row.create_time).format('YYYY-MM-DD HH:mm:ss') }}</span>
</template>
</el-table-column> <!-- 操作列-修改 -->
<el-table-column label="操作" align="center" width="120"> <template #default="scope">
<el-button type="text" @click="handleEdit(scope.row)">修改</el-button>
</template>
</el-table-column>
</el-table> <!-- 分页 -->
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize" @pagination="getList" /> <!-- 修改Value弹窗 -->
<el-dialog v-model="editDialogVisible" title="修改Cookies Value" :width="500" @close="resetEditDialog">
<el-form ref="editForm" :model="editForm" :rules="editRules" label-width="80px">
<el-form-item label="ID" prop="id">
<el-input v-model="editForm.id" disabled />
</el-form-item>
<el-form-item label="Key" prop="key">
<el-input v-model="editForm.key" disabled />
</el-form-item>
<el-form-item label="Value" prop="value">
<el-input v-model="editForm.value" type="textarea" :rows="6" placeholder="请输入修改后的Value" maxlength="10000"
show-word-limit />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="resetEditDialog">取消</el-button>
<el-button type="primary" @click="confirmEdit">确认修改</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup name="CookiesManagement">
//引入自己的接口路径
import dayjs from 'dayjs';
import { ref, reactive, toRefs, getCurrentInstance } from 'vue';
const { proxy } = getCurrentInstance();
const cookiesList = ref([]);
const loading = ref(true);
const showSearch = ref(true);
const total = ref(0); // 用于存储选中的行数据
const multipleSelection = ref([]); // 表格的ref,用于调用表格的方法
const multipleTable = ref(null); // 查询参数
const data = reactive({ queryParams: { pageNum: 1, pageSize: 10, key: undefined, name: undefined, }, });
const { queryParams } = toRefs(data); // 修改弹窗相关
const editDialogVisible = ref(false);
const editForm = reactive({ id: '', key: '', value: '' });
const editRules = { value: [{ required: true, message: '请输入修改后的Value', trigger: 'blur' }, { max: 10000, message: 'Value不能超过10000个字符', trigger: 'blur' }] };
/** 获取Cookies列表 */ function getList() {
loading.value = true;
const params = { ...queryParams.value };
getCookiesList(params).then(response => { cookiesList.value = response.data.data; total.value = response.data.total; loading.value = false; }).catch(error => { loading.value = false; proxy.$message.error('获取Cookies列表失败,请稍后重试'); console.error('获取列表失败:', error); });
}
/** 搜索按钮操作 */
function handleQuery() { queryParams.value.pageNum = 1; getList(); }
/** 重置按钮操作 */
function resetQuery() { proxy.resetForm("queryRef"); handleQuery(); }
/** 选择项变化时触发 */
function handleSelectionChange(val) { multipleSelection.value = val; }
/** 打开修改弹窗 */
function handleEdit(row) {
// 赋值当前行数据到修改表单
editForm.id = row.id; editForm.key = row.key; editForm.value = row.value; editDialogVisible.value = true; }
/** 确认修改Value */
function confirmEdit() { proxy.$refs.editForm.validate(async (valid) => { if (valid) { updateCookiesValue(editForm.id, editForm.value) .then(() => { proxy.$message.success('Value修改成功'); editDialogVisible.value = false; getList().catch(err => { proxy.$message.error('修改成功,但刷新列表失败'); console.error('列表刷新失败:', err); }); }) .catch((error) => {
// 捕获接口调用失败的错误
proxy.$message.error('修改时发生错误,请稍后重试'); console.error('修改失败:', error); }); } }); }
/** 重置修改弹窗 */
function resetEditDialog() { editForm.id = ''; editForm.key = ''; editForm.value = ''; proxy.resetForm('editForm'); editDialogVisible.value = false; }
// 初始加载列表
getList();
</script>
<style scoped>
.app-container {
padding: 20px;
}
.value-text {
color: #606266;
word-break: break-all;
}
</style>
问题原因: 获取当前实例的proxy方式在 Vue3 setup 中已失效,导致resetEditDialog函数执行时错误调用proxy.resetForm,清空了刚赋值的表单数据。
具体分析:在 Vue3 的<script setup>语法中,getCurrentInstance().proxy并非推荐且稳定的用法,尤其在最新版本的 Vue 或 Element Plus 中,该方式可能无法正确获取到组件实例,进而导致:
resetEditDialog函数异常:每次打开弹窗前,若误触发resetEditDialog(如弹窗关闭时),会通过无效的proxy调用resetForm,但实际可能未正确重置表单,或在某些场景下反向清空已赋值的editForm。- 数据赋值被覆盖:即使
handleEdit中给editForm赋了值,但后续若因proxy失效导致的表单重置逻辑异常,会覆盖已赋值的id、key、value,最终表现为弹窗无数据。
解决方案:
1.替换proxy,使用 Vue3 推荐的表单操作方式
在<script setup>中,无需通过getCurrentInstance获取proxy,直接使用ref获取表单实例,调用resetFields方法(Element Plus 表单的标准重置方法)。
- 调整弹窗关闭时的重置逻辑
为避免关闭弹窗时立刻清空数据,可将
resetEditDialog的清空逻辑延迟到弹窗打开前执行,而非关闭时
修改后的完整代码: