近期在修复测试提出的bug的时候发现了一个现象,在第二个弹窗的时候,取消第一个,第二个弹窗的内容不取消。因为第二个是个radio选择的table。所以要取消掉选择。
先看原先的操作
问题
第一步,点击新增,选择物料名称
第二步,点击物料展示物料选择弹窗
第三步点击保存,返回上层,物料名称赋值,点击取消
重新新增点击发现还是展示第二步的内容!!!,那么就不能忍了。为什么关闭之后重新展示不重新请求接口呢。
解决办法
咱们现在就去看看代码是如何解决的
第一层弹窗
//html
<template>
<BasicModal
v-bind="$attrs"
@register="registerModal"
:title="getTitle"
:width="1000"
@ok="handleSubmit"
>
<BasicForm @register="registerForm" style="margin: 20px 0">
<template #materialName="{ model, field }">
<InputSearch
placeholder="请选择物料名称"
v-model:value="model[field]"
:readonly="true"
@search="handleSearch()"
@click="handleSearch()"
:disabled="isUpdate"
/>
</template>
</BasicForm>
</BasicModal>
<bdAllMarBasClass @register="registerBdMarBasClassModal" @success="handleBdMarBasClassSuccess" />
</template>
<script lang="ts" setup>
import { ref, computed, unref } from 'vue';
import { InputSearch } from 'ant-design-vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { addFormSchema } from './data';
//第二层物料弹窗
import bdAllMarBasClass from '/@/views/tableModal/bdAllMarBasClass/index.vue';
import { useModal } from '/@/components/Modal';
const emits = defineEmits(['success', 'register']);
const isUpdate = ref(true);
const rowId = ref('');
const materialClassIds = ref('');
const [registerBdMarBasClassModal, { openModal: openBdMarBasClassModal }] = useModal();
// 物料表单table
const [registerForm, { setFieldsValue, resetFields, validate, getFieldsValue }] = useForm({
labelWidth: 100,
schemas: addFormSchema,
showActionButtonGroup: false,
actionColOptions: {
span: 12,
},
});
//弹窗
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields();
setModalProps({ confirmLoading: false });
isUpdate.value = !!data?.isUpdate;
if (unref(isUpdate)) {
rowId.value = data.record.id;
setFieldsValue({
...data.record,
isUpdate: isUpdate.value,
});
}
});
//弹窗标题
const getTitle = computed(() => (!unref(isUpdate) ? '新增库存预警指标' : '编辑库存预警指标'));
function handleSearch() {
openBdMarBasClassModal(true, getFieldsValue());
}
async function handleBdMarBasClassSuccess({ values }) {
setFieldsValue({
materialCode: values[0].code,
materialName: values[0].name,
materialTypeCode: values[0].materialClassCode,
materialTypeName: values[0].materialClassName,
spec: values[0].materialSpec,
model: values[0].materialType,
typeId: values[0].parentId,
});
materialClassIds.value = values[0].parentId;
}
async function handleSubmit() {
try {
const values = await validate();
setModalProps({ confirmLoading: true });
closeModal();
emits('success', {
isUpdate: unref(isUpdate),
values: { ...values, id: rowId.value },
});
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>
<style>
.ant-calendar-picker,
.ant-input-number {
width: 100%;
}
</style>
其实上面最主要的一个方法是什么呢?是这个getFieldsvalue 这个方法,它获取到了你form里面的所有的值,那么就能格局form的值的改变来判断是否需要重置第二个弹窗的值。
第二层弹窗
//物料页面
<template>
<BasicModal
width="80%"
v-bind="$attrs"
@register="registerModal"
title="选择物料"
okText="保存"
@ok="handleSubmit"
>
<PageWrapper contentClass="flex">
<DeptTree class="w-1/4 xl:w-1/5" @select="handleSelect" style="max-height: 500px" />
<BasicTable
class="w-3/4 xl:w-4/5"
style="padding-top: 4px"
@register="registerTable"
:maxHeight="400"
:searchInfo="searchInfo"
/>
</PageWrapper>
</BasicModal>
</template>
<script lang="ts" setup>
import { reactive } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { PageWrapper } from '/@/components/Page';
import { BasicTable, useTable } from '/@/components/Table';
import { bdMaterialList } from '/@/api/basicarchives/archives';
import { columns, searchFormSchema } from './data';
import DeptTree from './DeptTree.vue';
const emit = defineEmits(['success', 'register']);
const searchInfo = reactive<Recordable>({});
const [registerTable, { getSelectRows, reload, clearSelectedRowKeys, getForm }] = useTable({
columns: columns,
rowKey: 'id',
useSearchForm: true,
api: bdMaterialList,
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
autoSubmitOnEnter: true,
},
immediate: false,
rowSelection: { type: 'radio' },
});
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
if (data.materialCode === undefined && searchInfo.materialClassIds) {
getForm().resetFields();
clearSelectedRowKeys();
reload();
}
setModalProps({ confirmLoading: false });
});
function handleSelect(key) {
searchInfo.materialClassIds = key;
reload();
}
async function handleSubmit() {
const checkList = getSelectRows();
try {
setModalProps({ confirmLoading: true });
closeModal();
emit('success', {
values: checkList,
});
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>
其实其中最主要是使用clearSelectedRowKeys,getForm,然后在打开窗口的时候判断值是否存在,来看table是否清除。
小技巧
将一个意外发现的小技巧,如何打开的modal的第二个值不存在的话,那么打开的第二个弹窗只会触发一次useModalInner的事件。(就是下面的getFieldsValue不传的话)
这就是在vben开发中遇到的弹窗的table展示不刷新的解决方案,希望对大家以后的开发有帮助。