七、vben的modal弹窗不触发table刷新的问题

                       ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        

        近期在修复测试提出的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展示不刷新的解决方案,希望对大家以后的开发有帮助。

猜你喜欢

转载自blog.csdn.net/qq_43185384/article/details/127244039
今日推荐