Bootstrap

element-ui单个上传组件el-upload文件回显+el-table组件遍历上传+自定义文件列表+合并表格

在这里插入图片描述

一. 基本使用上传和回显

         <el-upload
              ref="upload"
              class="upload-demo"
              :limit="1"
              action=""
              accept=".png,.jpeg,.pdf,.xlsx"
              :http-request="handleChange"
              :before-remove="beforeremove"
              :file-list="uploadFileList"
              :on-preview="clickFile"
              :show-file-list="true"
            >
              <div class="uploadFiles">   <img src="@/assets/overview/Vector.png">上传文件</div>
            </el-upload></div>

回显文件数组uploadFileList 不能使用 uploadFileList [0]赋值,无法监听到文件的变化,要使用push等数组方法

      if (fileUrl) {
        this.$nextTick(() => {
          console.log('dsadasds', this.detailItem)
          this.uploadFileList.push(
            {
              url: fileUrl,
              name: fileName
            }
          )
          this.$forceUpdate()
        })
      } else {
        this.uploadFileList = []
        this.$forceUpdate()
      }

二. 自定义文件列表,进行新增上传和删除

  <el-table
      :data="tableData"
      border
      style="width: 100%; margin-top: 20px"
      :span-method="objectSpanMethod"
    >
      <el-table-column prop="riskSubtype" label="类别" width="180">
      </el-table-column>
      <el-table-column prop="detail" label="内容" width="600">
      </el-table-column>
      <el-table-column prop="uploadFileList" label="资料">
        <template #default="{ row, $index }">
          <el-upload
            class="uploadFile"
            ref="uploadFile"
            accept=".png,.jpeg,.pdf,.xlsx"
            multiple
            :limit="3"
            :on-exceed="handleExceed"
            :show-file-list="false"
            :http-request="
              (file) => {
                return uploadFileFn(file, $index);
              }
            "
          >
            <div class="uploadAttachments">
              <div class="upload_title">
                <div class="number">
                  附件({{
                    (row.uploadFileList && row.uploadFileList.length) || 0
                  }})
                </div>
                <div class="button_text">上传附件</div>
              </div>
            </div>
          </el-upload>
          <div
            class="attachmentList"
            v-if="row.uploadFileList && row.uploadFileList.length > 0"
          >
            <div class="attachmentList_item" v-for="item in row.uploadFileList">
              <img src="@/assets/img/success.png" />
              <div class="fileName">{{ item.FileName || "" }}</div>
              <img
                src="@/assets/img/delete.png"
                class="delete_icon"
                @click="beforeremoveFn(item, $index)"
              />
            </div>
          </div>
        </template>
      </el-table-column>
    </el-table>

1.实现合并同名的表格

定义 :span-method=“objectSpanMethod”

      mergeObj: {}, // 用来记录需要合并行的下标
      mergeArr: ["riskType", "riskSubtype"], // 表格中的列名
    // 构造合并的项
    getSpanArr(data) {
      this.mergeArr.forEach((key, index1) => {
        let count = 0; // 用来记录需要合并行的起始位置
        this.mergeObj[key] = []; // 记录每一列的合并信息
        data.forEach((item, index) => {
          // index == 0表示数据为第一行,直接 push 一个 1
          if (index === 0) {
            this.mergeObj[key].push(1);
          } else {
            // 判断当前行是否与上一行其值相等 如果相等 在 count 记录的位置其值 +1 表示当前行需要合并 并push 一个 0 作为占位
            if (item[key] === data[index - 1][key]) {
              this.mergeObj[key][count] += 1;
              this.mergeObj[key].push(0);
            } else {
              // 如果当前行和上一行其值不相等
              count = index; // 记录当前位置
              this.mergeObj[key].push(1); // 重新push 一个 1
            }
          }
        });
      });
    },
    // objectSpanMethod方法
    // 默认接受四个值 { 当前行的值, 当前列的值, 行的下标, 列的下标 }
    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      // 判断列的属性
      if (this.mergeArr.indexOf(column.property) !== -1) {
        // 判断其值是不是为0
        if (this.mergeObj[column.property][rowIndex]) {
          return [this.mergeObj[column.property][rowIndex], 1];
        } else {
          // 如果为0则为需要合并的行
          return [0, 0];
        }
      }
    },

2.添加,删除上传的文件

    // 删除
    beforeremoveFn(file, index) {
      this.$confirm(`确定移除 ${file.FileName}`).then(() => {
        const filePath = file.url;
        const i = this.tableData[index].uploadFileList.findIndex(
          (x) => x.url === filePath
        );
        this.tableData[index].uploadFileList.splice(i, 1);
      });
    },
    handleExceed(files, fileList) {
      this.$message.warning(
        `当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${
          files.length + fileList.length
        } 个文件`
      );
    },
    // 添加文件
    uploadFileFn(item, index) {
      this.$nextTick(() => {
        const fileName = item.file.name;
        const regex = /[@#\$%\^&\*]+/g;
        if (regex.test(fileName)) {
          this.$message.warning(
            "文件名不能存在 !@#¥%……&* 这种字符,请重新修改文件名"
          );
          return false;
        }
        const formData = new FormData();
        const file = item.file;
        formData.append("file", file);
        uploadCosVpp(formData)
          .then((res) => {
            if (res.data) {
              this.tableData[index].uploadFileList.push({
                FileName: this.getFileName(res.data.data),
                url: res.data.data,
              });
              this.$forceUpdate();
            }
          })
          .catch((err) => {
            this.$message.warning("文件上传失败");
          });
      });
    },
    getFileName(url) {
      var num = url.lastIndexOf("/") + 1;
      var fileName = url.substring(num);
      // 把参数和文件名分割开
      fileName = decodeURI(fileName.split("?")[0]);
      return fileName;
    },

3.深度监听表格的值

  watch: {
    tableData: {
      handler(value) {      
      },
      deep: true,
      immediate: true,
    },
  },

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;