组件的循环引用

163 阅读1分钟

1、递归组件:组件在自己的模板中调用自身。
2、循环引用:当父引用子,子引用父时。

直接给大家上代码:

  • 第一步,MulAnalysisResult.vue
<template>
  <div v-loading="loading">
    <div v-for="(item, index) in dataList" :key="index">
      <h6>{{ item.fileName }}</h6>
      <AnalysisResultTable :tableHeader="item.columns" :tableData="item.results" :height="'400px'"  ref="analysisResultTableRef" />
    </div>
  </div>
</template>

<script>
/* eslint-disable */
import { getTestResults } from "@/api/test";
import AnalysisResultTable from "../components/AnalysisResultTable.vue";

export default {
  name: "MulAnalysisResult",
  components: {
    AnalysisResultTable,
  },
  data() {
    return {
      loading: false,
      dataList: []
    };
  },
  created() {
    this.getList();
  },
  methods: {
    getList() {
      this.loading = true;
      getTestResults(this.$route.query.id)
        .then((res) => {
          const { code, data, msg } = res;
          if (code == 0) {
            this.dataList = data || [];
          } else {
            this.$message.error(msg);
          }
        })
        .finally(() => {
          this.loading = false;
        });
    },
  },
};
</script>

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

说明没有编写css样式,请自行编写

  • 第二步,AnalysisResultTable.vue
  <div>
    <el-table
      :data="tableData"
      style="width: 100%"
      :height="height"
      ref="table"
      :header-cell-style="{
        'background-color': '#FAFAFA',
        color: 'rgba(0, 0, 0, 0.85)',
        'font-weight': 'normal',
      }"
      size="small"
    >
      <template v-for="(item, index) in tableHeader">
        <el-table-column :min-width="120" :key="index" :prop="item.fName" show-overflow-tooltip>
          <template slot-scope slot="header">
            <el-tooltip
              effect="dark"
              :content="item.fName"
              placement="top"
              class="table-header"
            >
              <span>{{ item.fName }}</span>
            </el-tooltip>
          </template>
          <template slot-scope="scope">
            <el-input
              v-if="item.fType == '1'"
              placeholder="请输入"
              v-model="scope.row[item.fName]"
              size="mini"
              clearable
            />
            <div v-else-if="item.fType == '2' || item.fType == '3'">
              {{ scope.row[item.fName] }}
            </div>
            <div v-else class="name">
              <el-button size="small" type="text" @click="handleView(scope.row, item)"
                >查看</el-button
              >
            </div>
          </template>
        </el-table-column>
      </template>
    </el-table>
    <!-- 查看下转项 -->
    <TripItemDialog ref="TripItemRef" :addData="addData" />
  </div>
</template>

<script>
/* eslint-disable */
import TripItemDialog from "@/components/dialog/intelligentDecision/tripItem.vue";
export default {
  name: "analysisResultTable",
  components: { TripItemDialog },
  props: {
    tableData: {
      type: Array,
      required: true,
    },
    tableHeader: {
      type: Array,
      required: true,
    },
    height: {
      type: String,
      default: () => {
        return '100%';
      },
    },
  },
  data() {
    return {
      addData: {
        state: false,
        data: null,
        drillDownIds:[]
      },
      drillDownConfig: {
        columnName: null,
        columnValues: [],
        tableId: null,
        targetTableId: null,
        taskId: null
      },
    };
  },
  methods: {
    handleView(row, item) {
      this.drillDownConfig = {
        columnName: null,
        columnValues: [],
        tableId: null,
        targetTableId: null,
        taskId: null
      };
      const { currentTableId: tableId, fName: columnName, drillDownIds } = item;
      let taskId = this.$route.query.id;

      let tHeader = this.tableHeader.filter((item) => item.pk == 1);
      tHeader.forEach((m) => {
        for (let i in row) {
          if (m.fName == i) {
            this.drillDownConfig.columnValues.push({
              dataPk: m.viewColumn,
              dataValue: row[i],
            });
          }
        }
      });
      this.drillDownConfig.columnName = columnName;
      this.drillDownConfig.tableId = tableId;
      this.drillDownConfig.taskId = taskId;
      this.addData.state = true;
      this.addData.data = this.drillDownConfig;
      this.addData.drillDownIds = drillDownIds;
      this.$refs.TripItemRef.showData();
    },
  },
};
</script>
<style scoped lang="less"></style>

说明页面中使用弹框组件

  • 第三步,tripItem.vue
  <div>
    <el-dialog
      width="60%"
      :title="fileName"
      :visible="addData.state"
      @close="closeModal"
      @config="handleSubmit"
      append-to-body
      destroy-on-close
      :footer="false"
    >
      <div>
        <el-button
        type="primary"
        icon="el-icon-download"
        size="small"
        plain
        @click="exportTable"
        :loading="isExport"
        >导出</el-button
      >
      </div>
      <div v-loading="tableLoading">
          <div v-for="(item, index) in dataList" :key="index">
              <h6 class="com_title">{{ item.fileName }}</h6>
              <AnalysisResultTable
              :tableHeader="item.columns"
              :tableData="item.results"
              ref="analysisResultTableRef"
            />
          </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
/* eslint-disable */
import { testDown} from "接口地址";
import { exportExcel } from "@/util/exportExcel.js";

export default {
  name: "tripItem",
  components: {
    AnalysisResultTable: () =>
      import(
        "@/views/decisionPlatform/intelligentDecision/components/AnalysisResultTable.vue"
      ),
  },
  props: {
    addData: {
      type: Object,
      required: true,
    },
  },
  data() {
    return {
      fileName: "",
      tableLoading: false,
      dataList:[],
      isExport: false,
    };
  },
  methods: {
    showData() {
      this.tableLoading = true;
      this.dataList = [];

      if(this.addData.drillDownIds.length){
        this.addData.drillDownIds.forEach(item=>{
          this.addData.data.targetTableId = item;

          testDown(this.addData.data)
          .then((res) => {
            const { code, data, msg } = res;
            if (code === 0) {
              this.dataList = [...this.dataList, data] || [];
              this.tableLoading = false;
            } else {
              this.$message.error(msg);
            }
          })
          .finally(() => {
            this.tableLoading = false;
          });
        });
      }
    },
    exportTable() {
      this.isExport = true;
      exportExcel({
        url: `接口地址`,
        method: "post",
        data: this.addData.data,
      }).finally(() => {
        this.isExport = false;
      });
    },
    handleSubmit() {
      this.closeModal();
    },
    closeModal() {
      this.addData.state = false;
    },
  },
};
</script>

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

说明在此组件中循环引用AnalysisResultTable.vue组件

使用两种方式解决此问题:

1)方法

   components: {
     table: () =>import("@/views/2.vue"),
   },

2)方法

   beforeCreate() {
     const table = () => import("@/views/2.vue");
     this.$options.components.table = table;
   },

在生命周期beforeCreate()中动态插入组件。

鉴定完毕,欢迎友们一起交流学习!!