最近、テストで出たバグを修復していると、2つ目のポップアップウィンドウをキャンセルすると、1つ目のポップアップウィンドウはキャンセルされるが、2つ目のポップアップウィンドウの内容はキャンセルされないという現象が発見されました。2つ目はラジオで選んだテーブルだから。ですので、選択を取り消します。
最初に元の操作を見てください
質問
最初のステップは、[追加] をクリックして材料名を選択することです
2 番目のステップでは、マテリアルをクリックして、マテリアル選択ポップアップ ウィンドウを表示します。
3 番目のステップは、[保存] をクリックして上のレイヤーに戻り、マテリアル名を割り当てて、[キャンセル] をクリックすることです。
新しいクリックを追加して、2 番目のステップのコンテンツを発見または表示します。! ! 、それではたまらない。閉じてから再表示した後、インターフェイスを再要求しないのはなぜですか?
解決
コードが今それをどのように解決するか見てみましょう
ポップアップウィンドウの最初のレイヤー
//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 メソッドであり、フォームの値を変更することで、2 番目のポップアップ ウィンドウの値をリセットする必要があるかどうかを判断できます。
ポップアップ ウィンドウの第 2 層
//物料页面
<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 を使用して、ウィンドウを開いてテーブルがクリアされているかどうかを確認するときに、値が存在するかどうかを判断することです。
チップ
偶然発見されたちょっとしたトリックです。モーダルの 2 番目の値を開く方法が存在しないため、2 番目に開いたポップアップ ウィンドウは useModalInner イベントを 1 回だけトリガーします。(つまり、次の getFieldsValue が渡されない場合)
これは、vben の開発中に遭遇したポップアップ テーブルの表示が更新されない問題の解決策であり、今後の開発の参考になれば幸いです。