zoukankan      html  css  js  c++  java
  • elemnt和antv和ng动态表格的自定义列

    elemnt和antv和ng动态表格的自定义列

    帮助

    ng:NG-ZORRO

    antv:Ant Design Vue

    elemnt:element

    elment效果图

    echarts

    HTML
    <el-card>
          <div class="flex">
            <el-table :data="tableData" border>
              <el-table-column prop="name" label="筛查信息" align="center"> </el-table-column>
              <el-table-column v-for="(item, index) in header" :key="index" :prop="item.prop" :label="item.label" align="center">
                <template slot="header" slot-scope="scope">
                  <div class="close">
                    <el-popconfirm icon="el-icon-info" :ref="`popover-${scope.$index}`" @onConfirm="close(item)" icon-color="red" title="确定删除吗?"
                      ><el-button type="text" slot="reference">
                        <i class="el-icon-close" />
                      </el-button>
                    </el-popconfirm>
                  </div>
                  <el-select size="mini" v-model="item.schId" @change="schChange(item)" style=" 100%; margin-bottom: 10px" clearable placeholder="请选择学校">
                    <el-option v-for="(i, key) in schArr" :key="key" :label="i.schName" :value="i.schId"></el-option>
                  </el-select>
                  <el-select size="mini" v-model="item.batchId" @change="batchChange(item)" style=" 100%; margin-bottom: 10px" clearable placeholder="请选择批次">
                    <el-option v-for="(i, key) in batchArr" v-if="i.checkSchId == item.schId ? true : false" :key="key" :label="i.batchName" :value="i.batchId"></el-option>
                  </el-select>
                  <el-select size="mini" v-model="item.gradeId" @change="gradeChange(item)" style=" 100%; margin-bottom: 10px" clearable placeholder="请选择年级">
                    <el-option v-for="(i, key) in item.gradeArr" :key="key" :label="i.gradeName" :value="i.gradeId"></el-option>
                  </el-select>
                  <el-select size="mini" v-model="item.classId" @change="classChange(item)" style=" 100%" clearable placeholder="请选择班级">
                    <el-option v-for="(i, key) in item.classArr" :key="key" :label="i.className" :value="i.classId"></el-option>
                  </el-select>
                </template>
              </el-table-column>
            </el-table>
            <div class="btn" @click="add">添加对比报表</div>
          </div>
        </el-card>
    
    CSS
    .el-table {
      margin-top: 0;
      font-size: 12px;
    }
    .flex {
      display: flex;
      align-items: flex-start;
    }
    .btn {
       30px;
      height: 130px;
      text-align: center;
      background: #409efe;
      display: flex;
      justify-content: center;
      align-items: center;
      color: white;
      cursor: pointer;
    }
    .close {
      display: flex;
      justify-content: flex-end;
      margin-top: -10px;
    }
    
    JS
    created() {
        this.add()
        this.add()
        this.schlist()
        this.batchlist()
    },
    methods: {
        add() {
          this.header.push({
            prop: `index + ${this.index}`,
            schId: '',
            batchId: '',
            classId: '',
            gradeId: '',
            gradeArr: [],
            classArr: [],
          })
          this.index += 1
          this.schStatistics()
        },
        async schStatistics() {
          let a = []
          for (const key in this.header) {
            a.push({
              str: this.header[key].prop,
              schId: this.header[key].schId,
              gradeId: this.header[key].gradeId,
              classId: this.header[key].classId,
              batchId: this.header[key].batchId,
            })
          }
          const res = await this.$http.post('/***/****', a)
          if (res.data.code == 0) {
            let data = res.data.data
            for (const i in data) {
              let j = data[i].str
              this.tableData[0][j] = data[i].toScreenedPeopleNum + '/' + data[i].screenedPeopleNum
              this.tableData[1][j] = data[i].normalVisionPeopleNum + '/' + data[i].normalVisionPeopleRate + '%'
              this.tableData[2][j] = data[i].abnormalVisionPeopleNum + '/' + data[i].abnormalVisionPeopleRate + '%'
              this.tableData[3][j] = data[i].myopiaPeopleNum + '/' + data[i].myopiaPeopleRate + '%'
              this.tableData[4][j] = data[i].mildPeopleNum + '/' + data[i].mildPeopleRate + '%'
              this.tableData[5][j] = data[i].moderatePeopleNum + '/' + data[i].moderatePeopleRate + '%'
              this.tableData[6][j] = data[i].severePeopleNum + '/' + data[i].severePeopleRate + '%'
            }
          }
        },
    }
    

    ng效果图

    echarts

    HTML
    <nz-card>
          <div class="flex">
            <st
              #st
              (ngModelChange)="st.resetColumns({ emitReload: true })"
              [responsive]
              resizable
              [data]="listOfData"
              [columns]="header"
              style=" 100%"
            >
              <ng-template st-row="select" type="title" let-item let-index="index">
                <div style="display: flex; justify-content: flex-end; margin-bottom: 10px">
                  <a
                    nz-popconfirm
                    nzPopconfirmTitle="是否删除?"
                    nzPopconfirmPlacement="bottom"
                    (nzOnConfirm)="confirm(item)"
                    (nzOnCancel)="cancel()"
                    ><i nz-icon nzType="close" nzTheme="outline"></i
                  ></a>
                </div>
                <nz-select
                  style=" 100%; margin-bottom: 10px"
                  [(ngModel)]="item.batchId"
                  nzAllowClear
                  name="chosedBatch"
                  nzPlaceHolder="请选择检查批次"
                  (ngModelChange)="choseBatchChange(item, index)"
                >
                  <nz-option *ngFor="let i of batchList" [nzLabel]="i.batchName" [nzValue]="i.batchId"> </nz-option>
                </nz-select>
                <nz-select
                  style=" 100%; margin-bottom: 10px"
                  [(ngModel)]="item.gradeId"
                  name="chosedGrade"
                  nzPlaceHolder="请选择年级"
                  (ngModelChange)="choseGradeChange(item, index)"
                  nzAllowClear
                >
                  <nz-option *ngFor="let i of gradeList" [nzLabel]="i.gradeName" [nzValue]="i.gradeId"> </nz-option>
                </nz-select>
                <nz-select
                  style=" 100%"
                  [(ngModel)]="item.classId"
                  name="chosedClass"
                  nzPlaceHolder="请选择班级"
                  (ngModelChange)="choseClassChange(item, index)"
                  nzAllowClear
                >
                  <nz-option *ngFor="let i of item.classArr" [nzLabel]="i.className" [nzValue]="i.classId"> </nz-option>
                </nz-select>
              </ng-template>
            </st>
            <div class="btn" (click)="addRow()">添加对比报表</div>
          </div>
        </nz-card>
    
    CSS
    .btn {
      display: flex;
      align-items: center;
      justify-content: center;
       20px;
      height: 150px;
      padding: 15px;
      color: white;
      text-align: center;
      background: #409efe;
      cursor: pointer;
    }
    
    .select {
       100%;
      margin-bottom: 10px;
    }
    
    .flex {
      display: flex;
      align-items: flex-start;
       100%;
    }
    
    
    TS
    @ViewChild('st', { static: false }) private st: STComponent;
    header: any[] = [
        {
          title: '筛查信息',
          index: 'name',
        },
      ];
      listOfData: any[] = [
        {
          name: '待筛查/已筛查人数',
        },
        {
          name: '视力正常人数/比例',
        },
        {
          name: '视力异常人数/比例',
        },
        {
          name: '近视人数/比例',
        },
        {
          name: '轻度异常人数/比例',
        },
        {
          name: '中度异常人数/比例',
        },
        {
          name: '重度异常人数/比例',
        },
      ];
    addRow(): void {
        this.header.push({
          index: `index${this.i}`,
          batchId: null,
          classId: null,
          gradeId: null,
          gradeArr: [],
          classArr: [],
          renderTitle: `select`,
        });
        this.i++;
        this.sch();
      }
    
    ngOnInit(): void {
        this.addRow();
        this.addRow();
        this.gradeService.getAllGrades(1, 0, 1).subscribe((res) => {
          this.gradeListUploading = false;
          if (res && res.code != '0') {
            return;
          }
          this.gradeList = res.data;
        });
        this.reportService.getSelfSchBatchs().subscribe((res) => {
          if (res && res.code != '0') {
            return;
          }
          this.batchList = res.data;
        });
        this.schoolService.getSelfSchoolInfo().subscribe((res) => {
          if (res && res.code != '0') {
            return;
          }
          this.schId = res.data.schId;
        });
      }
      sch() {
        let a = [];
        for (let key = 1; key < this.header.length; key++) {
          a.push({
            str: this.header[key].index,
            schId: this.schId,
            gradeId: this.header[key].gradeId,
            classId: this.header[key].classId,
            batchId: this.header[key].batchId,
          });
        }
    
        this.schService.getSchStatistics(a).subscribe((res) => {
          if (res && res.code != '0') {
            return;
          }
          let data = res.data;
          for (let i = 0; i < data.length; i++) {
            let j = res.data[i].str;
            this.listOfData[0][j] = data[i].toScreenedPeopleNum + '/' + data[i].screenedPeopleNum;
            this.listOfData[1][j] = data[i].normalVisionPeopleNum + '/' + data[i].normalVisionPeopleRate + '%';
            this.listOfData[2][j] = data[i].abnormalVisionPeopleNum + '/' + data[i].abnormalVisionPeopleRate + '%';
            this.listOfData[3][j] = data[i].myopiaPeopleNum + '/' + data[i].myopiaPeopleRate + '%';
            this.listOfData[4][j] = data[i].mildPeopleNum + '/' + data[i].mildPeopleRate + '%';
            this.listOfData[5][j] = data[i].moderatePeopleNum + '/' + data[i].moderatePeopleRate + '%';
            this.listOfData[6][j] = data[i].severePeopleNum + '/' + data[i].severePeopleRate + '%';
          }
          this.st.resetColumns({ emitReload: true });
          this.st.reset();
          // console.log(this.header);
          console.log(this.listOfData);
        });
      }
    
    confirm(e): void {
        this.header = this.header.filter((item) => item.index != e.index);
        this.sch();
      }
    

    antV效果图

    echarts

    HTML
    <a-button
            class="editable-add-btn"
            @click="Visible = true"
            style="margin-bottom: 20px"
          >
            添加规格
          </a-button>
          <a-table
            :columns="columns"
            :data-source="dataSource"
            bordered
            :row-key="(dataSource) => dataSource.key"
            :pagination="false"
          >
            <!-- 动态 -->
            <template slot="1" slot-scope="text, record">
              <a-input
                allow-clear
                style=" 100px"
                v-model="record.dataVOS['0'].propertyValue"
              />
            </template>
            <template slot="2" slot-scope="text, record">
              <a-input
                allow-clear
                style=" 100px"
                v-model="record.dataVOS['1'].propertyValue"
              />
            </template>
            <template slot="3" slot-scope="text, record">
              <a-input
                allow-clear
                style=" 100px"
                v-model="record.dataVOS['2'].propertyValue"
              />
            </template>
            <template slot="4" slot-scope="text, record">
              <a-input
                allow-clear
                style=" 100px"
                v-model="record.dataVOS['3'].propertyValue"
              />
            </template>
    
            <template slot="5" slot-scope="text, record">
              <a-input
                allow-clear
                style=" 100px"
                v-model="record.dataVOS['4'].propertyValue"
              />
            </template>
            <template slot="7" slot-scope="text, record">
              <a-input
                allow-clear
                style=" 100px"
                v-model="record.dataVOS['6'].propertyValue"
              />
            </template>
            <template slot="8" slot-scope="text, record">
              <a-input
                allow-clear
                style=" 100px"
                v-model="record.dataVOS['7'].propertyValue"
              />
            </template>
            <template slot="9" slot-scope="text, record">
              <a-input
                allow-clear
                style=" 100px"
                v-model="record.dataVOS['8'].propertyValue"
              />
            </template>
    
            <template slot="skuCode" slot-scope="text, record">
              <a-input allow-clear style=" 100px" v-model="record.skuCode" />
            </template>
            <!-- 单位 -->
            <template slot="unit" slot-scope="text, record">
              <!-- <a-input allow-clear style=" 100px" v-model="record.unit" /> -->
              <a-select
                allow-clear
                v-model="record.unit"
                style=" 100px"
                show-search
                :filter-option="filterOption"
              >
                <a-select-option value="次">次</a-select-option>
                <a-select-option value="件">件</a-select-option>
                <a-select-option value="瓶">瓶</a-select-option>
                <a-select-option value="片">片</a-select-option>
                <a-select-option value="罐">罐</a-select-option>
                <a-select-option value="支">支</a-select-option>
                <a-select-option value="个">个</a-select-option>
                <a-select-option value="cm">cm</a-select-option>
                <a-select-option value="m">m</a-select-option>
                <a-select-option value="g">g</a-select-option>
                <a-select-option value="kg">kg</a-select-option>
                <a-select-option value="人">人</a-select-option>
              </a-select>
            </template>
            <!-- 成本价 -->
            <template slot="costPrice" slot-scope="text, record"
              ><a-input
                allow-clear
                style=" 100px"
                v-model="record.costPrice"
              />
            </template>
            <!-- 零售价 -->
            <template slot="retailPrice" slot-scope="text, record">
              <a-input
                allow-clear
                style=" 100px"
                v-model="record.retailPrice"
              />
            </template>
            <!-- 状态 -->
            <template slot="isDel" slot-scope="text, record">
              <a-switch
                checked-children="正常"
                un-checked-children="停用"
                v-model="record.isDels"
              />
            </template>
            <!-- 允许折扣 -->
            <template slot="isDiscount" slot-scope="text, record">
              <a-switch
                checked-children="是"
                un-checked-children="否"
                v-model="record.isDiscount"
              />
            </template>
            <!-- 允许积分 -->
            <template slot="isUsePoint" slot-scope="text, record">
              <a-switch
                checked-children="是"
                un-checked-children="否"
                v-model="record.isUsePoint"
              />
            </template>
            <!-- 图片 -->
            <template slot="image" slot-scope="text, record, index">
              <div>
                <a-upload
                  :action="url"
                  :headers="headers"
                  list-type="picture-card"
                  method="post"
                  :file-list="record.imgArr"
                  @preview="handlePreview"
                  @change="
                    (fileList) => {
                      return handleChange(fileList, index);
                    }
                  "
                >
                  <div v-if="record.imgArr.length < 1">
                    <a-icon type="plus" />
                    <div class="ant-upload-text">上传</div>
                  </div>
                </a-upload>
                <a-modal
                  :visible="previewVisible"
                  :footer="null"
                  @cancel="handleCancel"
                >
                  <img alt="example" style=" 100%" :src="previewImage" />
                </a-modal>
              </div>
            </template>
            <!-- 操作 -->
            <template slot="operation" slot-scope="text, record">
              <a-popconfirm
                v-if="dataSource.length > 1"
                title="是否删除?"
                @confirm="() => onDelete(record)"
              >
                <a href="javascript:;">删除</a>
              </a-popconfirm>
            </template>
          </a-table>
          <a-button
            class="editable-add-btn"
            @click="TdAdd"
            style="margin-top: 20px"
          >
            添加参数
          </a-button>
    
    JS
    data(){
        return{
            // 表格
          dataSource: [
            {
              key: 0,
              costPrice: "",
              dataVOS: [],
              imgArr: [],
              image: "",
              isDels: true,
              isDiscount: true,
              isUsePoint: true,
              map: {},
              productId: "",
              propertyId: "",
              propertyName: "",
              propertyValue: "",
              propertyValueId: "",
              retailPrice: "",
              salesNum: "",
              skuCode: "",
              stockNum: "",
              unit: "",
            },
          ],
          size: [
            "颜色",
            "度数",
            "材质",
            "重量",
            "尺寸",
            "规格",
            "型号",
            "设计",
            "容量",
            "疗程",
            "近视度数",
            "散光度数",
            "轴位",
            "功能",
          ],
          Visible: false,
          Loading: false,
          count: 1,
          counts: 1,
          columns: [
            {
              title: "单位",
              dataIndex: "unit",
              scopedSlots: { customRender: "unit" },
              align: "center",
            },
            {
              title: "成本价",
              dataIndex: "costPrice",
              scopedSlots: { customRender: "costPrice" },
              align: "center",
            },
            {
              title: "零售价",
              dataIndex: "retailPrice",
              scopedSlots: { customRender: "retailPrice" },
              align: "center",
            },
            {
              title: "状态",
              scopedSlots: { customRender: "isDel" },
              align: "center",
            },
            {
              title: "允许折扣",
              scopedSlots: { customRender: "isDiscount" },
              align: "center",
            },
            {
              title: "允许积分",
              scopedSlots: { customRender: "isUsePoint" },
              align: "center",
            },
            {
              title: "条形码(skucode)",
              dataIndex: "skuCode",
              scopedSlots: { customRender: "skuCode" },
              align: "center",
            },
            {
              title: "图片",
              dataIndex: "image",
              scopedSlots: { customRender: "image" },
              align: "center",
            },
            {
              title: "操作",
              dataIndex: "operation",
              scopedSlots: { customRender: "operation" },
              align: "center",
            },
          ],
          // 图片
          previewVisible: false,
          previewImage: "",
          headers: {
            Authorization: localStorage.getItem("***"),
          },
          url: process.env.VUE_APP_BASEURL + "/****/****",  
        }
    }
    created() {
        this.baseProductDetail();
    },
    methods: {
        // 详情
        async baseProductDetail() {
          let res = await this.$http.get("/***/***", {
            params: {
              id: this.$props.row.id,
            },
          });
          if (res.data.success == true) {
            this.$nextTick(() => {
              this.form.setFieldsValue({
                brandId: res.data.data.baseProduct.brandId,
                categoryId: res.data.data.baseProduct.categoryId,
                englishName: res.data.data.baseProduct.englishName,
                manufacturer: res.data.data.baseProduct.manufacturer,
                name: res.data.data.baseProduct.name,
                productCode: res.data.data.baseProduct.productCode,
                pyCode: res.data.data.baseProduct.pyCode,
                remark: res.data.data.baseProduct.remark,
                supplierId: res.data.data.baseProduct.supplierId,
                warnNum: res.data.data.baseProduct.warnNum,
                warnDay: res.data.data.baseProduct.warnDay,
              });
            });
            if (res.data.data.productSkuList != null) {
              let arr = [];
              for (const key in res.data.data.productSkuList) {
                res.data.data.productSkuList[key].isDels =
                  res.data.data.productSkuList[key].isDel == 0 ? true : false;
              }
              this.dataSource = res.data.data.productSkuList;
              for (const key in this.dataSource) {
                this.dataSource[key].key = this.dataSource[key].id;
                arr.push(this.dataSource[key].id);
                this.dataSource[key].imgArr = [];
                if (this.dataSource[key].image != "") {
                  this.dataSource[key].imgArr.push({
                    uid: "-1",
                    name: "image.png",
                    status: "done",
                    response: {
                      data: this.dataSource[key].image,
                    },
                    url: process.env.VUE_APP_BASEURL + this.dataSource[key].image,
                  });
                }
                if (this.dataSource[key].dataVOS == null) {
                  this.dataSource[key].dataVOS = [];
                }
              }
              let max = Math.max(...arr);
              this.count = max + 1;
              this.dataSource[0].nameArr =
                this.dataSource[0].propertyName.split(",");
              if (this.dataSource[0].dataVOS.length > 0) {
                let Arr = [];
                for (const i in this.dataSource[0].dataVOS) {
                  Arr.push(this.dataSource[0].dataVOS[i].propertyId);
                  let newData = {
                    title: (
                      <div>
                        {this.dataSource[0].dataVOS[i].propertyName}
                        <a
                          onClick={() =>
                            this.onDel(this.dataSource[0].dataVOS[i].propertyName)
                          }
                        >
                          <a-icon type="close" style="margin-left:5px" />
                        </a>
                      </div>
                    ),
                    key: this.dataSource[0].dataVOS[i].propertyName,
                    scopedSlots: {
                      customRender: this.dataSource[0].dataVOS[i].propertyId,
                    },
                    align: "center",
                  };
                  this.columns.unshift(newData);
                }
    
                let Max = Math.max(...Arr);
                this.thIndex = Max + 1;
              } else {
                this.thIndex = 1;
              }
            }
          }
        },
        // 删除参数
        onDelete(key) {
          const dataSource = [...this.dataSource];
          this.dataSource = dataSource.filter((item) => item.key !== key.key);
          this.removeIds.push(key.id);
        },
        // 删除规格
        onDel(key) {
          console.log(key);
          const columns = [...this.columns];
          this.columns = columns.filter((item) => item.key !== key);
          console.log(this.dataSource);
          if (this.dataSource.length > 0) {
            for (const key in this.dataSource) {
              for (const i in this.dataSource[key].dataVOS) {
                if (this.dataSource[key].dataVOS[i].propertyName == key) {
                  this.dataSource[key].dataVOS[i].split(i, 1);
                }
              }
            }
          }
        },
        ThAdd() {
          const { checkedList } = this;
          for (let key = 0; key < checkedList.length; key++) {
            for (let i = 0; i < this.columns.length; i++) {
              if (this.columns[i].key == checkedList[key]) {
                this.$message.error(checkedList[key] + "重复");
                this.Visible = false;
                return;
              }
            }
            let newData = {
              title: (
                <div>
                  {checkedList[key]}
                  <a onClick={() => this.onDel(checkedList[key])}>
                    <a-icon type="close" style="margin-left:5px" />
                  </a>{" "}
                </div>
              ),
              key: checkedList[key],
              scopedSlots: { customRender: this.thIndex },
              align: "center",
            };
            this.columns.unshift(newData);
            for (let i = 0; i < this.dataSource.length; i++) {
              if (this.dataSource[i].dataVOS) {
                this.dataSource[i].dataVOS.push({
                  propertyId: this.thIndex,
                  propertyName: checkedList[key],
                  propertyValue: "",
                  propertyValueId: this.thIndex,
                });
              }
            }
            this.thIndex += 1;
          }
    
          this.Visible = false;
          this.checkedList = [];
        },
        TdAdd() {
          const { count } = this;
          const newData = {
            imgArr: [],
            key: this.count,
            costPrice: "",
            dataVOS: [],
            image: "",
            isDels: true,
            isDiscount: true,
            isUsePoint: true,
            productId: "",
            propertyId: "",
            propertyName: "",
            propertyValue: "",
            propertyValueId: "",
            retailPrice: "",
            salesNum: "",
            skuCode: "",
            stockNum: "",
            unit: "",
          };
          if (this.dataSource.length > 0) {
            for (const key in this.dataSource[0].dataVOS) {
              newData.dataVOS.push({
                propertyName: this.dataSource[0].dataVOS[key].propertyName,
                propertyId: this.dataSource[0].dataVOS[key].propertyId,
                propertyValueId: this.dataSource[0].dataVOS[key].propertyValueId,
              });
            }
          }
    
          this.dataSource.push(newData);
          this.count = count + 1;
        },
    }
    

    问题:ng遇到的问题比较多,可能是我属性用的还不是很熟练,表格的话我是在NG-ALAIN里找到的普通版本的表头和表格是分开的动态列渲染不了(可能是单纯的我菜)

  • 相关阅读:
    教材全解
    知乎、博客园等开放API接口
    学习正则表达式就这么简单
    C#操作域用户ADHelper
    跨线程时使用静态扩展方法更新控件
    C#中的WinForm的消息机制简述,及消息机制下Invoke,和BeginInvoke的使用和区别
    WinForm 捕获异常 Application.ThreadException + AppDomain.CurrentDomain.UnhandledException
    Winform异常处理之ThreadException、unhandledException及多线程异常处理
    深入理解C#中的IDisposable接口
    批处理应用的几个技巧
  • 原文地址:https://www.cnblogs.com/xz233/p/14927633.html
Copyright © 2011-2022 走看看