vue使用问题记录:父组件通过props传给子组件数据,后改变数据,要使用nextTick,否则修改滞后,可能造成bug

发布时间 2024-01-02 15:26:50作者: dirgo

问题如标题所写

代码示例:

父组件:

<template>
  <div class="">
    <div class="">
      <t-form ref="formData" :data="data.formData" colon label-width="100px" label-align="right" :rules="rules">
        <!--        <t-form-item label="事项id" name="matterId">-->
        <!--          <t-input v-model="data.formData.matterId" />-->
        <!--        </t-form-item>-->
        <t-form-item label="单元格key" name="cellKey">
          <t-input v-model="data.formData.cellKey" readonly />
        </t-form-item>
        <t-form-item label="所属月份" name="ssyf">
          <i-selector v-model="data.formData.ssyf" dickey="ssyf" />
        </t-form-item>
        <t-form-item label="文本位置" name="textAlign">
          <i-selector v-model="data.formData.textAlign" dickey="text_align" />
        </t-form-item>
        <t-form-item label="数据类型" name="dataType">
          <i-selector v-model="data.formData.dataType" dickey="matter_cell_data_type" />
        </t-form-item>
        <t-form-item v-if="data.formData.dataType === '3'" label="文本内容" name="textContent">
          <t-input v-model="data.formData.textContent" />
        </t-form-item>
        <t-form-item v-if="data.formData.dataType === '2'" label="运算表达式" name="formula">
          <t-input v-model="data.formData.formula" />
        </t-form-item>
      </t-form>
    </div>
    <div>
      <salary-matter-cell-source-table
        v-if="data.formData.dataType === '1'"
        ref="cellSourceTable"
        :key="data.formData.cellKey"
        :set-id="data.formData.id"
      ></salary-matter-cell-source-table>
    </div>
    <layer-bottom-bar :actions="actionButtons" />
  </div>
</template>

<script setup lang="ts" name="MatterCellSetter">
import { watch } from 'vue';
import SalaryMatterCellSetLayerHandler from './index.t';
import { SalaryMatterCellSourceTable } from '@/pages/modules/devel-server-salary/matterCellSource/page';

const props = defineProps<{
  params: any;
}>();

const handler = new SalaryMatterCellSetLayerHandler(props);
const { data, formData, actionButtons, getCellEntity, rules, cellSourceTable } = handler;
// 初始化
// init();
defineExpose({ getCellEntity });
watch(
  () => data.formData.dataType,
  newValue => {
    if (newValue && !data.formData.cellKey) {
      formData.value.validate();
    }
  }
);
watch(
  () => data.formData,
  newValue => {
    if (newValue) {
      console.log('====单元格配置主表---变化==data.formData==', newValue);
    }
  }
);
</script>

<style scoped lang="scss"></style>

操作data.formData变化

save = async () => {
    const validDate = await this.formData.value.validate();
    if (typeof validDate === 'boolean' && validDate) {
      // 这里执行保存方法
      // 保存主表
      const { isOk, message, data } = await saveEntity(this.data.formData);

      if (isOk()) {
        // **注意使用nextTick使this.data.formData的变化立即生效
        await nextTick(() => {
          this.data.formData = data;
        });
        // 如果 dataType类型 是 数据库,再保存 cellSource 配置项
        if (this.data.formData.dataType === '1') {
          //
          // 保存 数据库配置,调用子组件cellSourceTable里暴露的方法saveSources,传 set 对象过去,添加matterId,setId等字段
          const { isOk } = await this.cellSourceTable.value.saveSources(this.data.formData);
          if (isOk) {
            await successMessage('单元格配置保存成功!');
          } else {
            await errorMessage('保存数据库配置项目出错,请联系管理员处理');
          }
          // await successMessage('保存成功!');
        } else {
          await successMessage('单元格配置保存成功!');
        }
      } else {
        await errorMessage(message);
      }
      // if (this.props.callback) {
      //   setTimeout(() => {
      //     this.props.callback();
      //   }, 300);
      // }
      // this.close();
    }
  };

子组件里的saveSources方法,用到了props传来的参数this.props.setId

saveSources = async cellSet => {
    console.log('===单元格类型:数据库===保存==单元格数据源=====cellId====', cellSet);
    console.log('===单元格类型:数据库===保存==单元格数据源==222==this.data.tableValue=====', this.data.tableValue);
    // 循环添加 setId
    this.data.tableValue = this.data.tableValue.map(s => {
      s.matterId = cellSet.matterId;
      s.cellKey = cellSet.cellKey;
      s.setId = cellSet.id;
      return s;
    });

    // 先获取纯正对象,因为vxe-table会向里面添加其他属性,导致后台保存报错
    const sources = toRaw(this.data.tableValue).map(item => {
      // eslint-disable-next-line no-underscore-dangle
      delete item._X_ROW_KEY;
      return item;
    });
    console.log('===单元格类型:数据库===保存==单元格数据源====sources=====', sources);
    console.log('===单元格类型:数据库===保存==单元格数据源====this.props.setId=====', this.props.setId);
    return saveSourceList(this.props.setId, sources);
  };

 

nextTick(() => {