8、Vben フレームワークは編集可能なテーブルを動的に生成します

        開発の過程で、プロダクトマネージャーが奇妙な要件を提示し、人々を非常に混乱させました.顧客のニーズはこのようなものであったため、さまざまな開発方法しか考えられませんでした.

        最近、2つの要件が提起されました。

        1つ目は、日付を選択する際の時間選択に応じて、2つの時間の間の日付を下の表に追加するもので、下は実現後の効果です。

        2 つ目は動的追加処理モジュールで、タブやテーブルだけでなく、フォームなどのコンポーネントや、行の追加や削除などの操作も含まれますが、この操作は非常に面倒で実装が非常に困難です。

        さて、「不死鳥は鳳凰」という言葉がありますが、恐れずに前に進むことでのみ涅槃から生まれ変わることができるのです。詳しく説明させてください。

        最初にファイルの構成を見てください。update.vue ファイルがメイン ページで、updateSon.vue ファイルがそのサブページとしての基になるプロセス ファイルです。

最初の要件実現計画:

1.まず、彼の時間間隔を分析して取得します

//当时间改变的时候触发handleChangeDate方法
<template #date="{ model, field }">
          <RangePicker
            v-model:value="model[field]"
            valueFormat="YYYY-MM-DD"
            format="YYYY-MM-DD"
            style="
               {
                width: '100%';
              }
            "
            @change="handleChangeDate"
          />
 </template>


//在script里写方法,使用provide依赖注入一下,方便子组件无限级使用。
  // 选择周期
  const dateList = ref([]);
  function handleChangeDate(e) {
    setFieldsValue({ demandPlanningCycleStart: e[0], demandPlanningCycleEnd: e[1] });
    dateList.value = enumerateDaysBetweenDates(e[0], e[1]);
  }
  provide('dateList', dateList);

//处理时间函数,return时间区间
  function enumerateDaysBetweenDates(startDate, endDate) {
    // 假定你已经保证了startDate 小于endDate,且二者不相等
    let daysList = [];
    let SDate = moment(startDate);
    let EDate = moment(endDate);
    daysList.push(SDate.format('MM-DD'));
    while (SDate.add(1, 'days').isBefore(EDate)) {
      // 注意这里add方法处理后SDate对象已经改变。
      daysList.push(SDate.format('MM-DD'));
    }
    daysList.push(EDate.format('MM-DD'));
    return daysList;
  }

2. updateSon.vue ページで dateList を取得し、テーブルの列に追加します。

//在BasicTable里面循环增加tamplate
//ifDetail是在详情展示的时候是他不被编辑


 <template #[`planDay${idx+1}`]="{ record }" v-for="(val, idx) in dateList" :key="idx">
      <InputNumber
      :precision="2"
      @blur="handleDataInsert"
      placeholder="请输入"
      :disabled="ifDetail"
      v-model:value="record[`planDay${idx + 1}`]"
      />
</template>


//获取到dateList的值
  const dateList: any = inject('dateList');

//在watch监听的时候监听这个值,然后将新出现的日期插入columns里面
//item.demandPlanDetailList.tableMethods.getColumns()获取到了最新的columns
//columns为

  watch(
    dateList,
    (newVal, oldVal) => {
      purchasePlan.value.forEach((item) => {
        const columns1: any = [];
        const tableColumns = item.demandPlanDetailList.tableMethods.getColumns();
        if (newVal.length) {
          newVal.forEach((date, index) => {
            columns1.push({
              title: date,
              width: 140,
              slots: { customRender: `planDay${index + 1}` },
              dataIndex: `planDay${index + 1}`,
            });
          });
          columns1.push({
            title: '合计',
            width: 140,
            slots: { customRender: 'planDayDemandSum' },
            dataIndex: 'planDayDemandSum',
          });
        }
        if (oldVal.length) {
//删除原先插入的
          tableColumns.splice(11, oldVal.length + 1);
        }
//增加最新的进去
        tableColumns.splice(11, 0, ...columns1);
        item.plannedOutputDetail.tableMethods.setColumns(columns);
        item.demandPlanDetailList.tableMethods.setColumns(tableColumns);
      });
    },
    { deep: true },
  );


第二の要求実現計画

  1. まず、表示用の子コンポーネントにデフォルト値を渡す必要があります。
//当然也需要provide依赖注入一下,方便子组件无限级使用。
const purchasePlan = ref([]);
 provide('purchasePlan', purchasePlan);

 //默认新增数据,最重要的是无论schemas和table里面的columns都要使用cloneDeep解除他们的深度绑定,才能重复使用。
  const addData = (datalist) => {
    const [registerForm, formMethods] = useForm({
      baseColProps: {
        span: 8,
      },
      layout: 'vertical',
      labelWidth: 140,
      schemas: cloneDeep(UpdateFormStaticSchema()),
      showActionButtonGroup: false,
    });
    const [registerPlanTable, tablePlanMethods] = useTable({
      ...
    });
    const [registerTable, tableMethods] = useTable({
      ...
    });
    const [registerOtherTable, tableOtherMethods] = useTable({
      ...
    });
    const [registerPriceTable, tablePriceMethods] = useTable({
     ...
    });
    datalist.push({
      activeKey: 0,
      form: {
        form: registerForm,
        formMethods: formMethods,
      },
      plannedOutputDetail: {
        table: registerPlanTable,
        tableMethods: tablePlanMethods,
      },
      demandPlanDetailList: {
        table: registerTable,
        tableMethods: tableMethods,
      },
      otherCostDetailList: {
        table: registerOtherTable,
        tableMethods: tableOtherMethods,
      },
      operation: {
        table: registerPriceTable,
        tableMethods: tablePriceMethods,
      },
    });
  };

2. クリックしてプロセスを追加する場合、テーブルの名前をハードコーディングしてはならないことを明確にする必要があるため、値を割り当てる必要があります。

//按钮触发方法    
//purchasePlan为原需要展示几个工序,从外面获取,默认是1个
<a-button
 	style="margin-right: 15px"
    type="primary"
    @click="addPurchasePlanListBtn(purchasePlan)"
   >
   添加工序
</a-button>

//获取数据
const purchasePlan: any = inject('purchasePlan');

//最重要的是这步,让他的所有的方法和form和table增加到purchasePlan中
  const addPurchasePlanListBtn = (datalist) => {
    const [registerForm, formMethods] = useForm({
      ...
    });
    const [registerTable, tableMethods] = useTable({
     ...
    });
    const [registerPlanTable, tablePlanMethods] = useTable({
      ...
    });
    const [registerOtherTable, tableOtherMethods] = useTable({
      ...
    });
    const [registerPriceTable, tablePriceMethods] = useTable({
      ...
    });
    datalist.push({
      activeKey: 0,
      form: {
        form: registerForm,
        formMethods: formMethods,
      },
      plannedOutputDetail: {
        table: registerPlanTable,
        tableMethods: tablePlanMethods,
      },
      demandPlanDetailList: {
        table: registerTable,
        tableMethods: tableMethods,
      },
      otherCostDetailList: {
        table: registerOtherTable,
        tableMethods: tableOtherMethods,
      },
      operation: {
        table: registerPriceTable,
        tableMethods: tablePriceMethods,
      },
    });
  };

        このステップが実現されたので、誰もがそれがどのように追加されるかを理解し、追加されるたびに上記のテーブルとフォームがすべて作成されます。

では、これで今日の分かち合いは終わりです。それでもわからないことがあれば、メッセージを残してください。一つ一つお答えします。

おすすめ

転載: blog.csdn.net/qq_43185384/article/details/129161833