“This is the 16th day of my participation in the First Challenge 2022. For details: First Challenge 2022.”

A, requirements,

Based on the project requirements, you need to implement a table of the following form.

Second, the implementation

Since the framework used for the project is VUE + Element UI, we can consider using Element UI’s Table component for implementation. However, after understanding, the data structure required by the component does not seem to meet the implementation of this function. Through research, we can customize the JSON data required for table rendering, so that it can be easily implemented, the specific approach is as follows:

1. Define the JSON data required by the table component (tabledata.json)

{" header_labels ": {" header1_label" : {" label ":" 1 "merchants," children ": {" header1_col1" : ""," header1_col2 ": ""," header1_col3 ":" "}}, "header2_label" : {" label ":" merchants 2 ", "children" : {" header2_col1 ":" ", "header2_col2" : ""," header2_col3 ":" "}}, "header3_label" : {" label ":" 3 "merchants," children ": {" header3_col1" : ""," header3_col2 ": ""," header3_col3 ":" "}}}, "col_values" : [{" header1_col1 ":" inventory (a) ", "header1_col2" : "20000", "header2_col1" : ", "header2_COL2 ": "21000"," header3_COL1 ": "Inventory ", "header3_col2": "22000"}, {"header1_col1": "Total Units "," Header1_COL2 ": "15000", "Header2_COL1 ":" Total Units ", "Header2_COL2 ": "7850"," header3_COL1 ": {" header1_COL1 ": "date "," header1_COL2 ": "Sales ", "header1_col3":" sales ", "header1_col3": "Lower Volume "," header2_COL1 ": "date "," header2_COL2 ": "upper volume "," header2_COL3 ": "Lower volume "," header3_COL1 ": "Date "," header3_COL2 ": "top unit "," header3_COL3 ": "bottom unit"}, {" header1_COL1 ": "2022.02.01", "header1_col2": "400", "header1_col3" : "300", "header2_col1" : "2022.02.01", "header2_col2" : "20", "header2_col3" : "300", "header3_col1" : "2022.02.01", "header3_col2" : "40", "header3_col3" : "30"}, {" header1_col1 ": "2022.02.02", "header1_col2" : "700", "header1_col3" : "800", "header2_col1" : "2022.02.02", "header2_col2" : "30", "header2_col3" : "800", "header3_col1" : "2022.02.02", "header3_col2" : "70", "header3_col3" : "80"}, {" header1_col1 ":" 2022.02.03 ", "header1_col2" : "900", "header1_col3" : "1000", "header2_col1" : "" header2_col2 2022.02.03", ":" 40 ", "header2_col3" : "1000", "header3_col1" : "2022.02.03", "header3_col2" : "90", "header3_col3" : "100"}, {" header1_col1 ":" 2022.02.041 ", "header1_col2" : "1100", "header1_col3" : "1100", "header2_col1" : "2022.02.04", "header2_col2" : "50", "header2_col3" : "1100", "header3_col1" : "2022.02.04", "header3_col2" : "110", "header3_col3" : "110"}, {" header1_col1 ":" 2022.02.05 ", "header1_col2" : "1300", "header1_col3" : "1200", "header2_col1" : "2022.02.05", "header2_col2" : "60", "header2_col3" : "1200", "header3_col1" : "2022.02.05", "header3_col2" : "130", "header3_col3" : "120"}, {" header1_col1 ": "2022.02.06", "header1_COL2 ": "1400"," header1_COL3 ": "1500", "header2_COL1 ": "2022.02.06", "header2_col2": "70", "header2_col3" : "1500", "header3_col1" : "2022.02.06", "header3_col2" : "140", "header3_col3" : "150"}, {" header1_col1 ":" 2022.02.07 ", "header1_col2" : "1700", "header1_col3" : "1600", "header2_col1" : "2022.02.07", "header2_col2" : "80", "header2_col3" : "1600", "header3_col1" : "2022.02.07", "header3_col2" : "170", "header3_col3": "160" } ] }Copy the code

2, in the JS definition of tableData rendering required variables (tableData), and obtain local JSON data (tabledata.json) assigned to the tableData variable.

<script> import tableJsonData from '/static/ tabledata. json' export default {data() {return {tableData: {} } }, created() { this.tableData = tableJsonData } } </script>Copy the code

3. HTML page rendering

<template> <div class="app-container"> <! <el-table :data="tableData['col_values']" style="width: 100%; border height="600" > <! - tableData [' header_labels] : --> <el-table-column V-for ="(value1,key1,index1) in tableData['header_labels']" :key="index1" :label="value1['label']" align="center" > <el-table-column v-for="(value2,key2,index2) in value1['children']" :key="index2" align="center" > <template slot-scope="scope"> <span>{{ scope.row[key2] }}</span> </template> </el-table-column> </el-table-column> </el-table> </div> </template>Copy the code

4. Page effect

As you can see from the image above, the basic look of the page has been worked out, but there are still some issues that need to be optimized:

  1. The second line is obviously redundant and we want to hide it;
  2. On the third and fourth lines, we want to do a cell merge where the values are displayed;
  3. Make a change to the display text cell style to make it more contrast;

Three, optimize

1. Hide blank lines

For the first, you can fix this by setting the “header-cell-class-name” property provided by the Table component.

First set this property on the el-table tag as follows:

    <el-table
      :data="tableData['col_values']"
      style="width: 100%;"
      border
      height="600"
      :header-cell-class-name="hiddenHeaderRow"
    >
Copy the code

Write hiddenHeaderRow in methods as follows:

HiddenHeaderRow ({rowIndex}) {if (rowIndex === 1) {return 'hiddenClass'}},Copy the code

Write the hiddenClass style in style as follows:

.hiddenClass{
  display: none;
}
Copy the code

It looks like this, where the white space has been hidden:

2. Merge cells

For the second point, the Table component also provides a property “span-method” that lets you combine cells.

Again, set this property on the el-table tag as follows:

    <el-table
      :data="tableData['col_values']"
      style="width: 100%;"
      border
      height="600"
      :header-cell-class-name="hiddenHeaderRow"
      :span-method="arraySpanMethod2"
    >
Copy the code

Implementing arraySpanMethod2 in methods:

arraySpanMethod2({ rowIndex, columnIndex }) { if (rowIndex <= 1) { if (columnIndex % 3 === 1) { return [1, Else if (columnIndex % 3 === 2) {return [0, 0]}}},Copy the code

It looks like this, with the cells merged:

3. Style modification

The third point can also be modified by using the “cell-class-name” property of the Table component.

Set this property on the el-Table tag as follows:

    <el-table
      :data="tableData['col_values']"
      style="width: 100%;"
      border
      height="600"
      :header-cell-class-name="hiddenHeaderRow"
      :span-method="arraySpanMethod2"
      :cell-class-name="addClass2"
    >
Copy the code

Implement addClass2 method in methods:

    addClass2({ rowIndex, columnIndex }) {
      if (rowIndex <= 1 && columnIndex % 3 === 0) {
        return 'sonStyle'
      } else if (rowIndex === 2) {
        return 'sonStyle'
      }
    },
Copy the code

Define sonStyle style in style:

.sonStyle{
  font-weight: bold;
  background-color: #f0f9eb;
  font-size: 14px;
  color: #27a2ff;
}
Copy the code

The final result is shown as follows:

I also wrote about complex tables earlier: Vue + Element UI dynamically implements diversified tables (including vertical tables, multi-level table headers, cell merging, editable, collapsible, and custom styles)