Requirements and final implementation
Requirements:
- Tables can be zoomed in full screen
- The header is frozen, the two columns on the left are frozen, and the one column on the right is frozen
- Merge cells in the first column
- Second column cell click and highlight
- last column frozen
- Cell Color Scale Settings
- Scroll bar customization
- Column headers are also merged
- adaptive form
- The table lines of the cells are also drawn by themselves
Problem and solution
Question 1: After the form is enlarged in full screen, it is full screen, zoom in and zoom out, scroll bar
solution:
The vue-fullscreen component, most of the problems encountered are in the style, just simply adjust it
npm install npm install vue-fullscreen --save Add in the main.js file import VueFullscreen from "vue-fullscreen"; Vue. use(VueFullscreen);
Question 2: Style incompatibility and self-adaptation problems encountered in frozen rows and columns
solution:
Use 100% for the width, and dynamically set the height and maxheight of the column for the height. Note that if you set maxheight and the frozen column at the same time and modify the height of the scroll bar (reducing the height of the scroll bar), it may cause the frozen column to take up Dissatisfaction, this is because the frozen column of el-table reserves the position of the scroll bar, because after setting the maxheight of the entire table, the frozen column will also calculate a maxheight by itself. When we dynamically set the maxheight of the table, we must also The maxheight of the frozen column is set
Question 3: Merging problems, all need to use the built-in attributes of el-table
solution:
Merge with :span-method="objectSpanMethod"
to set merge rules, I use the same name merge
To merge rows, you need to nest another el-table-column tag with the el-table-column tag
Question 4: About cell color scale and click event
solution:
Cell color scale: :cell-style
Cell click: @cell-click
Code: There are a little more codes, it is recommended to look at the idea
<template> <div class="compass-content"> <div class="top"> <div class="topContent"> <div class="top-left"> <full screen :page-only="true" v-model="fullscreen" :exit-on-click-wrapper="false" fullscreen-class="big-view bg-white" > <div :class="fullscreen ? 'city-contentTSFull' : 'city-contentTS'" v-loading="loading" element-loading-background="rgba(24, 41, 88, 0)" > <!-- <el-button @click="toggle" class="fullButton" >{<!-- -->{<!-- --> fullscreen ? "Exit" : "Enter" }}fullscreen</el-button > --> <img class="fullImg" @click="toggle" src="../../assets/images/quanping.png" alt="" /> <!-- <img v-else @click="toggle" src="../../assets/images/quanping.png" alt="" /> --> <el-table ref="myTable" :data="tableDataTOP" style="width: auto;" :fit="true" :max-height="BomHeights" :cell-style="cellStyle" :span-method="objectSpanMethod" @cell-click="cellClick" :row-key="row => row.id" > <el-table-column fixed="left" prop="column name" label="column name" align="center" width="120" > <template slot-scope="scope"> <div> <!-- <img class="listimg1" src="../../assets/images/.png" alt="" /> --> <span class="listcol1">{<!-- -->{<!-- --> scope.row.column name }}</span> </div> </template> </el-table-column> <el-table-column fixed="left" prop="column name" label="column name" align="center" width="120" > <template slot-scope="scope"> <el-tooltip v-if="scope.row.column name.length > 6" class="item" effect="dark" :content="scope.row.column name" placement="bottom" > <div class="cell-content" alt="111"> {<!-- -->{<!-- --> nameFormatter(scope.row.column name) }} </div> </el-tooltip> <div v-else class="cell-content" alt="111"> {<!-- -->{<!-- --> scope.row.column name }} </div> </template> </el-table-column> <el-table-column label="column name" align="center"> <el-table-column prop="QYSL" label="column name" width="150" align="center" > </el-table-column> <el-table-column prop="ZCZB" label="column name)" width="150" align="center" > </el-table-column> <el-table-column prop="SJZB" label="column name" width="150" align="center" > </el-table-column> <el-table-column prop="SSQYSL" label="column name" width="150" align="center" > </el-table-column> </el-table-column> <el-table-column fixed="right" label="Operation" width="100" align="center" > <template slot-scope="scope"> <el-button @click="handleClick(scope.row)" type="text" size="small" >Jump</el-button > </template> </el-table-column> </el-table> </div> </fullscreen> </div> </div> </div> <el-dialog :title="partTitle" :visible.sync="modalMy" :modal-append-to-body="false" custom-class="colorModal" width="60vw" > <section class="l-box"> <div class="l-ent-info"> <div class="l-ent-info-box"> <div class="tableBoxItem"> <div class="itemBody"> <div class="chartsBar" v-loading="loadingFormChart" element-loading-background="rgba(24, 41, 88, 0)" > <div v-show="noDataBar == false" id="bar" class="chartViewBar" ></div> <p v-if="noDataBar" style="text-align:center;font-size: 16px;color: #fff" > No data </p> </div> <!-- <div class="tuBox" partTitle="Excellent Enterprise Development & amp;Enterprise Type"> </div> --> </div> </div> </div> </div> </section> <!-- <div slot="footer" class="dialog-footer" style="text-align: center;"> <el-button @click="modalMy = false">Close</el-button> </div> --> </el-dialog> </div> </template> <script> import Vue from "vue"; import {<!-- --> tempNum } from "@/utils/index"; // import DevelopmentTrend from "./components/DevelopmentTrend.vue"; import {<!-- --> interface } from "@/api"; export default {<!-- --> data() {<!-- --> return {<!-- --> targetRowId: 0, mapShow: true, //control map map display noData: false, pieChart: null, pageNum: 1, currentPage: 1, news: [], noDataBar: false, tableDataQyList: [], pageSize: 20, total: null, barChart: null, scatterChart: null, loading: false, scatterLoading: false, indLoading: false, trendLoading: false, BomHeights: 0, industryList: [], industryValue: "", params: {<!-- -->}, industryTypeData: [], //Industry research and judgment industryTypeValue: "", fullscreen: false, listcol1Length: [], modalMy: false, //Control popup window modalMyList: false, partTitle: "", //The name of the currently selected module partTitleList: "", //list title lineargroup: [], roleList: [], tableDataTOP: [], tableData: [], tableDataRight: [], heightWatch: "", areaMyCode: "", clickedRow: 0, clickedColumn: 1, CYFLCode: "", CYMC Code: "", }; }, watch: {<!-- --> CYMCCode() {<!-- --> this. pieView(); // this. getFilterLabels this. industryChange(); }, heightWatch(newValue) {<!-- --> let _this = this; console. log(newValue); this.$nextTick(() => {<!-- --> _this. tablechange(); this.$nextTick(() => {<!-- --> _this. changeMaxHeight(); }); }); } }, computed: {<!-- --> getRowClass() {<!-- --> return function(row) {<!-- --> return row.highlight ? "highlight-row" : ""; }; } }, mounted() {<!-- --> this. getTopList(); this.pieChart = this.$echarts.init(document.getElementById("pie")); window.addEventListener("resize", this.chartResize); let _this = this; this.$nextTick(function() {<!-- --> _this.heightWatch = document.getElementsByClassName( "top-left" )[0].scrollHeight; }); window.onresize = function() {<!-- --> _this.heightWatch = document.getElementsByClassName( "top-left" )[0].scrollHeight; }; }, methods: {<!-- --> //full screen toggle() {<!-- --> this.fullscreen = !this.fullscreen; this.BomHeights = this.fullscreen ?window. innerHeight - 50 : document.getElementsByClassName("top-left")[0].scrollHeight * 0.9; let _this = this; this.$nextTick(() => {<!-- --> _this. tablechange(); this.$nextTick(() => {<!-- --> _this. changeMaxHeight(); }); }); }, //table height setting tablechange() {<!-- --> this.BomHeights = this.fullscreen ?window. innerHeight - 50 : document.getElementsByClassName("top-left")[0].scrollHeight * 0.9; }, //table maxheight setting changeMaxHeight() {<!-- --> const fixedBodyWrapper = this.$refs.myTable.$el.querySelectorAll( ".el-table__fixed-body-wrapper" ); const BodyWrapper = this.$refs.myTable.$el.querySelector( ".el-table__body-wrapper" ); //The height of the frozen column -8p is the height of the scroll bar fixedBodyWrapper[0].style.maxHeight = BodyWrapper.style.maxHeight.split("px")[0] - 8 + "px"; fixedBodyWrapper[1].style.maxHeight = BodyWrapper.style.maxHeight.split("px")[0] - 8 + "px"; const fixedBodyWrapperTwo = this.$refs.myTableTwo.$el.querySelectorAll( ".el-table__fixed-body-wrapper" ); const BodyWrapperTwo = this.$refs.myTableTwo.$el.querySelector( ".el-table__body-wrapper" ); fixedBodyWrapperTwo[0].style.maxHeight = BodyWrapperTwo.style.maxHeight.split("px")[0] - 8 + "px"; }, //Cell color scale setting cellStyle({<!-- --> row, column, rowIndex, columnIndex }) {<!-- --> //Flexible modification if (columnIndex != 1 & amp; & amp; columnIndex != 0 & amp; & amp; columnIndex != 20) {<!-- --> let ageData = "transparent"; if (row[column.property] != 0) {<!-- --> // Get the data of the corresponding column const columnData = this.tableDataTOP.map( item => item[column.property] ); console.log("columnData", columnData); // Sort according to the value of the data const sortedColumnData = columnData. sort((a, b) => b - a); console.log("sortedColumnData", sortedColumnData); // Calculate the position of the data in the percentage range const index = sortedColumnData. findIndex( item => item === row[column.property] ); console.log("index", index); const percentage = Math.ceil( ((index + 1) / sortedColumnData. length) * 100 ); console.log("percentage", percentage); if (percentage <= 10) {<!-- --> ageData = "rgba(18, 0, 255, 1)"; } else if (percentage <= 20) {<!-- --> ageData = "rgba(1, 92, 229, 1)"; } else if (percentage <= 40) {<!-- --> ageData = "rgba(63, 148, 186, 1)"; } else if (percentage <= 70) {<!-- --> ageData = "rgba(19, 60, 140, 1)"; } else {<!-- --> ageData = "rgba(4, 6, 94, 1)"; } } else {<!-- --> ageData = "transparent"; } return {<!-- --> backgroundColor: `${<!-- -->ageData} !important`, cursor: "pointer" }; } //Selected style of the second column if (rowIndex === this.clickedRow & amp; & amp; columnIndex === 1) {<!-- --> return {<!-- --> border: `1px solid #2C89E5 !important` }; } if (columnIndex === 1) {<!-- --> return {<!-- --> cursor: "pointer" }; } }, //cell click cellClick(row, column, cell, event) {<!-- --> //Forbid click if ( column.label === "column name" || column.label == "column name" || column.property == "column name" ) {<!-- --> //block event. stopPropagation(); // Here you can add other logic to restrict clicks } else if (column.label === "column name") {<!-- --> this.clickedRow = row.$index; this. locateRow("", true); } else {<!-- --> this.showModal(column.label, column.property); } // console. log(row, column, cell, event); }, /* table merge columns and rows */ objectSpanMethod({<!-- --> rowIndex, columnIndex }) {<!-- --> if (columnIndex === 0) {<!-- --> const _row = this.flitterData(this.tableDataTOP).one[rowIndex]; // console. log("_row", _row); const _col = _row > 0 ? 1 : 0; return {<!-- --> rowspan:_row, colspan: _col }; } }, /**Merge the first column of the table, process the table data Here is the same merge*/ flitterData(arr) {<!-- --> let spanOneArr = []; let concatOne = 0; arr.forEach((item, index) => {<!-- --> if (index === 0) {<!-- --> spanOneArr. push(1); } else {<!-- --> //Note that the typeName here is a field bound to the table, change it according to your own needs if (item.typeName === arr[index - 1].typeName) {<!-- --> //The first column needs to merge the judgment conditions of the same content spanOneArr[concatOne] += 1; spanOneArr. push(0); } else {<!-- --> spanOneArr. push(1); concatOne = index; } } }); return {<!-- --> one: spanOneArr }; }, //Industry name can display up to 6 children, beyond hidden nameFormatter(cellValue) {<!-- --> // console. log(cellValue); if (cellValue. length > 6) {<!-- --> return cellValue. slice(0, 6) + "..."; } else {<!-- --> return cellValue; } }, nameTooltip(row) {<!-- --> // console. log(row); return row. date; }, //header style headerCellStyle() {<!-- --> return {<!-- --> background: "rgba(11, 87, 252, 0.38)", boxShadow: "inset 0 0 20px rgba(11, 87, 252, 1)" }; }, // Get the above list value async getTopList() {<!-- --> this. pieView(); this.roleList = await interface(); let {<!-- --> data } = await interface(); //Set a unique value for each row of data this.tableDataTOP.forEach((item, index) => {<!-- --> item. $index = index; }); }, //Click to pop up the popup window showModal(type, labelValue) {<!-- --> let _this = this; _this.modalMy = true; _this.$nextTick(() => {<!-- --> _this.lineview(type, labelValue); }); _this. partTitle = type; }, // View details jump handleClick(row) {<!-- --> // console. log(row); let _this = this; let param = {<!-- --> // activeCode: _this.tooltipContent.code }; const {<!-- --> href } = this.$router. resolve({<!-- --> path: "jump route", query: param }); // window.open(href, "_blank"); _this.$router.push(href); }, }, }; </script> <style lang="less" scoped> .top {<!-- --> flex: 1; height: 0; margin: 0px 26px 20px 26px; // display: flex; // flex-direction: row; background: url("../../assets/images/patternTop.png") no-repeat center center; background-size: cover; .topContent {<!-- --> height: 90%; display: flex; flex-direction: row; } & amp; .top-left {<!-- --> padding-left: 34px; flex: 0.7; width: 0; .listimg1 {<!-- --> } .listcol1 {<!-- --> background: url("../../assets/images/tableColList1.png") no-repeat center center; line-height: 42px; font-size: 16px; font-family: Microsoft YaHei; font-weight: 400; color: #ffffff; display: block; } } & amp; .top-right {<!-- --> padding-right: 25px; flex: 0.3; width: 0; background-size: 100% 100%; display: flex; flex-direction: column; } } ::v-deep.el-table, ::v-deep.el-table__expanded-cell {<!-- --> background-color: transparent !important; } .city-title {<!-- --> display: flex; flex-direction: row; height: 70px; font-size: 16px; font-family: Microsoft YaHei; font-weight: 400; color: #ffffff; // line-height: 44px; .city-title-left {<!-- --> // line-height: 70px; padding: 25px 40px; } .city-title-right {<!-- --> line-height: 35px; } } .city-content, .city-contentTS, .city-contentTSFull, .itemBody {<!-- --> ::v-deep.el-table th, ::v-deep.el-table tr, ::v-deep .el-table td {<!-- --> background-color: transparent !important; border: 0; //Remove the form } /*Remove the bottom border*/ ::v-deep.el-table td.el-table__cell {<!-- --> border: 0; } /* The background color of the table */ ::v-deep .el-table thead {<!-- --> background: rgba(11, 87, 252, 0.3); box-shadow: inset 0 0 50px #0b57fc; } ::v-deep.el-table th.el-table__cell.is-leaf {<!-- --> border: 0; } ::v-deep .el-table--border th.gutter:last-of-type {<!-- --> border-bottom-width: 0px; } ::v-deep.no-border.el-table__header-wrapper {<!-- --> border: 0; } ::v-deep.no-border.el-table__body-wrapper {<!-- --> border: 0; } ::v-deep .el-table::before {<!-- --> background: none; } ::v-deep .el-table::after {<!-- --> background: none; } ::v-deep.el-table--border, .el-table--group {<!-- --> border: 0; } // ::v-deep td, // th {<!-- --> // border: 1px solid rgba(141, 149, 165, 0.4); // } ::v-deep thead {<!-- --> font-size: 14px; font-family: Microsoft YaHei; font-weight: 400; color: #ffffff; tr:nth-child(1) {<!-- --> th:nth-child(1) {<!-- --> border-right: 1px solid rgba(141, 149, 165, 0.4); } } tr:nth-child(1) {<!-- --> th {<!-- --> border-bottom: 1px solid rgba(141, 149, 165, 0.4); border-right: 1px solid rgba(141, 149, 165, 0.4); } th:nth-child(1) {<!-- --> border-bottom: 0; } } tr:nth-child(2) {<!-- --> th:nth-child(4), th:nth-child(7), th:nth-child(16), th:nth-child(18) {<!-- --> border-right: 1px solid rgba(141, 149, 165, 0.4); } } tr {<!-- --> th {<!-- --> border-right: 0; } } } ::v-deep.el-table__row {<!-- --> font-size: 16px; font-family: Microsoft YaHei; font-weight: 400; color: #ffffff; td {<!-- --> padding: 2px 0; border-top: 0; border-bottom: 0; } td:nth-child(1), td:nth-child(2), td:nth-child(6), td:nth-child(9), td:nth-child(18) {<!-- --> border-right: 1px solid rgba(141, 149, 165, 0.4); } // td:nth-child(2n + 1) {<!-- --> // border-right: 1px solid rgba(141, 149, 165, 0.4); // } // td:last-of-type {<!-- --> // border-right: 0; // } } } .city-contentTS, .city-contentTSFull {<!-- --> height: 100%; ::v-deep.el-table th, ::v-deep.el-table tr, ::v-deep .el-table td {<!-- --> background-color: transparent !important; border: 1px solid rgba(141, 149, 165, 0.4); //Remove the form } /*Remove the bottom border*/ ::v-deep.el-table td.el-table__cell {<!-- --> border: 1px solid rgba(141, 149, 165, 0.4); } .fullImg {<!-- --> width: 18px; height: 18px; z-index: 50; position: fixed; top: 121px; left: 68%; } } .itemBody {<!-- --> ::v-deep.el-table th, ::v-deep.el-table tr, ::v-deep .el-table td {<!-- --> background-color: transparent !important; border: 1px solid rgba(141, 149, 165, 0.4); //Remove the form } } .city-contentTSFull {<!-- --> height: 100%; padding-top: 30px; ::v-deep .el-table__body-wrapper::-webkit-scrollbar {<!-- --> width: 6px; height: 6px; } .fullImg {<!-- --> width: 18px; height: 18px; z-index: 1000; position: fixed; top: 7px !important; left: 98.5% !important; } } /**Set the scroll bar about el-table*/ //Scroll bar length and width ::v-deep .el-table__body-wrapper::-webkit-scrollbar {<!-- --> z-index: 5 !important; // position: relative; // top: 10px; // right: 10px; width: 3px; height: 8px; } //scroll bar style ::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb {<!-- --> box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2); z-index: 1000; border-radius: 0px; background-color: rgba(0, 138, 255, 1); } //scroll bar floating ::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb:hover {<!-- --> background-color: rgba(0, 138, 255, 1); } //scroll bar background ::v-deep .el-table__body-wrapper::-webkit-scrollbar-track {<!-- --> background-color: rgba(77, 178, 255, 0.38); border-radius: 0px; } //scroll bar intersection ::v-deep .el-table__body-wrapper::-webkit-scrollbar-corner {<!-- --> // display: none; background-color: rgba(77, 178, 255, 0.38); } .big-view {<!-- --> z-index: 999; } ::v-deep.el-table__fixed {<!-- --> right: 0 !important; bottom: 0 !important; } ::v-deep.el-table__fixed-right {<!-- --> right: 3px !important; bottom: 0 !important; } ::v-deep .el-table__body-wrapper {<!-- --> .el-table--scrollable-y {<!-- --> z-index: 51 !important; } } ::v-deep .el-table__body-wrapper {<!-- --> overflow-y: scroll !important; } ::v-deep.el-table__fixed-body-wrapper {<!-- --> // max-height: 200px !important; } ::v-deep .el-table__fixed-right .el-table__fixed-body-wrapper {<!-- --> background: #03277c; box-shadow: -6px 0px 16px 0px rgba(0, 15, 47, 0.45); } ::v-deep .el-table__fixed .el-table__fixed-body-wrapper, .el-table__fixed-header-wrapper {<!-- --> background: #03277c; } ::v-deep .el-table__fixed-right .el-table__fixed-header-wrapper {<!-- --> background: #03277c; } ::v-deep .el-table__fixed .el-table__fixed-header-wrapper {<!-- --> background: #03277c; } ::v-deep.el-table__fixed::before {<!-- --> height: 0; } ::v-deep .el-table__fixed-right::before {<!-- --> height: 0; } ::v-deep.el-table__fixed-right-patch {<!-- --> // display: none; width: 3px !important; background: rgba(11, 87, 252, 0.3); box-shadow: inset 0 0 50px #0b57fc; border-bottom: 0; } ::v-deep .el-table th.gutter {<!-- --> display: table-cell !important; } .cell-content {<!-- --> white-space: nowrap !important; overflow: hidden !important; text-overflow: ellipsis !important; } /deep/.colorModal {<!-- --> background: url("../../assets/images/modalBg.png") no-repeat center center; background-size: 101% 101%; .el-dialog__header {<!-- --> display: flex; align-items: center; justify-content: center; padding: 30px 15px; .el-dialog__title {<!-- --> color: #fff; font-size: 26px; & amp;::before {<!-- --> display: none; } } .el-dialog__headerbtn {<!-- --> right: 60px; .el-dialog__close {<!-- --> font-size: 20px; color: #fff; } } } .el-dialog__body {<!-- --> padding: 30px 50px; } .itemBody {<!-- --> } } .itemBody {<!-- --> height: 50vh; } .tuBox {<!-- --> width: 100%; height: 100%; display: flex; & amp; > div {<!-- --> width: 0; flex: 1; height: 100%; } } </style>