Uni-app does not use tables, but hands a table with merged cells

(If the project is urgent, copy the code directly, if not urgent, there are ideas behind can be kangkang) effect mapThe downside is that the height is fixed, this feeling can be adaptive (as long as it works for now), add a click event display content for now, displaying these table data in H5 is not very friendly.

(tdRowspan) (tdRowspan) (tdRowspan) (tdRowspan) (tdRowspan) TdColspan represents how many cells the column occupies (column merge)

PackHeader: [{A: {td: "tdRowspan: 1, tdColspan: 10,}, B: {td: "", tdRowspan: 0, tdColspan: 0,}, C: {td: "", tdRowspan: 0, tdColspan: 0, }, D: { td: "", tdRowspan: 0, tdColspan: 0, }, E: { td: "", tdRowspan: 0, tdColspan: 0, }, F: { td: "", tdRowspan: 0, tdColspan: 0, }, G: { td: "", tdRowspan: 0, tdColspan: 0, }, H: { td: "", tdRowspan: 0, tdColspan: 0, }, I: { td: "", tdRowspan: 0, tdColspan: 0, }, J: { td: "", tdRowspan: 0, tdColspan: 0, } }, { A: {td: "listing item ", tdRowspan: 2, tdColspan: 1,}, B: {TD:" listing item content ", tdRowspan: 2, tdColspan: 1,}, C: {td: "List amount ", tdRowspan: 2, tdColspan: 1,}, D: {td:" change amount ", tdRowspan: 1, tdColspan: 2,}, E: {td: "", tdRowspan: 2, tdColspan: 1,}, E: {td: "", tdRowspan: 2, tdColspan: 1,} 0, tdColspan: 0,}, F: {td: "cumulative completed by the end of the semester ", tdRowspan: 2, tdColspan: 1,}, G: {TD:" cumulative completed by the end of the semester ", tdRowspan: 2, tdColspan: 1,}, G: {TD: "cumulative completed by the end of the semester ", 1,}, H: {td: "completed ", tdRowspan: 2, tdColspan: 1,}, J: {td:" completed ", tdRowspan: 2, tdColspan: 1,}, J: {td: "Note ", tdRowspan: 2, tdColspan: 1,}, {A: {td: "", tdRowspan: 0, tdColspan: 0,}, B: {td: "", tdRowspan: 2, tdColspan: 1,}, {td:" 0, tdColspan: 0,}, C: {td: ", tdRowspan: 0, tdColspan: 0,}, D: {td: ", tdRowspan: 0, tdColspan: 0,}, E: {td: "changes in current supervision of audit," tdRowspan: 1, tdColspan: 1,}, F: {td: "", tdRowspan: 0, tdColspan: 0,}, G: {td:" ", tdRowspan: 0, tdColspan: 0, }, H: { td: "", tdRowspan: 0, tdColspan: 0, }, I: { td: "", tdRowspan: 0, tdColspan: 0, }, J: { td: "", tdRowspan: 0, tdColspan: 0, } }, { A: { td: "", tdRowspan: 1, tdColspan: 1, }, B: { td: "", tdRowspan: 1, tdColspan: 1, }, C: { td: "", tdRowspan: 1, tdColspan: 1, }, D: { td: "", tdRowspan: 1, tdColspan: 1, }, E: { td: "", tdRowspan: 1, tdColspan: 1, }, F: { td: "", tdRowspan: 1, tdColspan: 1, }, G: { td: "", tdRowspan: 1, tdColspan: 1, }, H: { td: "", tdRowspan: 1, tdColspan: 1, }, I: { td: "", tdRowspan: 1, tdColspan: 1, }, J: { td: "", tdRowspan: 1, tdColspan: 1, } } ],Copy the code

LetterHeadData is an array of [“A”,”B”,…..”F”], etc., generated in JS

<scroll-view class="scrool-more" scroll-x="true" @scroll="scroll" scroll-left="0">
    <view class="da-table" >
      <view class="da-table-head" >
        <view class="da-table-head-tr"  v-for="(item, index) in packHeader" :key="index" >
            <template v-for="(hitem, hindex) in letterHeadData" >
                <view class="da-table-head-th" :key="hindex"
                :style="(item[hitem].tdColspan && (item[hitem].tdColspan * 1 >= 1) ? 'width:' + item[hitem].tdColspan * 200 + 'px! important; ' : 'display:none! important; ') + (item[hitem].tdRowspan ? 'height:' + (item[hitem].tdRowspan ) * 40 + 'px! important; ' : '') + (item[hitem].tdFloat ? 'position:absolute! important; background:white; z-index:999; ':')">
                        <text class="da-thead-th-text" > {{ item[hitem].td }} </text>
                </view>
          <! -- add this to make which grid help floating grid occupy position -->
                <view :key="hindex + 'float'"  v-if="item[hitem].tdFloat "
                :style="(item[hitem].tdColspan ? 'width:' + item[hitem].tdColspan * 200 + 'px! important; display: inline-block! important; visibility: hidden; ' : 'display: inline-block! important; ')">
                        <text>Look at me</text>
                </view>
            </template>
        </view>
      </view>
    </view>
</scroll-view>
Copy the code

Next comes the JS that generates letterHeadData.

// Get the alphabet head of the header
getlitterTableHead() {
        let azData = this.AZsort()
        let tableLength = Object.keys(this.packHeader[0]).length
        this.letterHeadData = azData.splice(0, tableLength) // Remember to declare this
        console.log(this.letterHeadData, tableLength, 'dadada'.this.packHeader[0])},// Generate an array
AZsort() {
        let arr = [];
        for (let i = 0; i < 26; i++) {
                arr.push(String.fromCharCode((65 + i)))
                // console.log(String.fromCharCode((65 + i)))  
                // console.log(i)   
        }

        for (let j = 0; j < 26; j++) {
                for (let c = 0; c < 26; c++) {
                        arr.push(arr[j] + arr[c])
                        // console.log(arr[j]+String.fromCharCode((65 + c)))}}return arr;
},
Copy the code

Here are some inline code slices.

generateMergeTable() {
        let tableLength = this.packHeader.length // How many rows does the table have
        for (let i = 0; i < tableLength; i++) {
                let keyData = this.packHeader[i] // Get the data for this row
                // Traversal determines that the cell occupies two rows and takes it out of the document flow
                Object.keys(keyData).forEach(key= >{ 
                        console.log(keyData[key].tdRowspan)
                        if (keyData[key].tdRowspan * 1> =2) {
                                keyData[key].tdFloat = true 
                                if (i + 1 < tableLength) {
                                        / / how many rows
                                        let firstTemp = this.packHeader[i + 1]
                                        / / which columns
                                        firstTemp[key].tdColspan = keyData[key].tdColspan * 1}}})}Copy the code

And then there’s the styling side of it which is really a bit of a hassle with CSS.

.da-table{
        display: inline-table;
        padding:10px;
        transform: scale(0.7);
        transform-origin: 0 0;
        margin-bottom: 20px;
}

.da-table-head{
        position: relative;
        border-left: 1px solid #5d5d5d;
        border-bottom: 1px solid #5d5d5d;
}

.da-table-head-tr{
        position: relative;
        min-height: 40px;
        display: block;
}

.da-table-head-th{
        border-right:1px solid #5d5d5d;
        border-top: 1px solid #5d5d5d;
        position: relative;
        display: inline-block;
        word-break: normal! important; text-align: center; padding-left: 10upx; vertical-align: top; line-height: 40px; height: 40px; overflow: hidden; } .da-table-body {border: 1px solid #5d5d5d;
        border-top: 0px;
        border-right: 0px;
}
.da-thead-th-text{
        white-space: normal;
        word-break: break-all;
        font-size:16px;
        overflow: hidden;
        position: absolute;
        top: 48%; /* offset, centered */ 
        left: 0;
        right: 0;
        transform: translateY(-50%)! important; line-height: 17px; } .scrool-more{ white-space: nowrap; width:100%;  
        display: inline-block; 
}
Copy the code

Train of thought

V -for=”(item, index) in packHeader” V -for=”(hitem, hindex) in letterHeadData” so I loop through each key, And then merge columns, I think merge columns is to take up the right position, make it several times as wide as it used to be, just so we don’t have tdColspan 0 in our data, so the width of the position is greater than 0, so the width of the position is tdColspan * (you want the width). 0 * tdColspan is 0, but the border is in, so set display: None; Just don’t let it show, (● strap strap ●)

There’s a couple of things to think about when you combine columns, one of them is you change the height, you don’t change the cell next to you, you get inconsistent heights, like this

I’m going to use position:absolute; The height is not affected, but the following cells are pushed to the left because they are out of the document flowThen it is very uncomfortable, –, think about it, or add a false block under the floating element to occupy the position, the result is really, absolutely. Here are some of themInline code slice. That’s why I wrote this code

<view :key="hindex + 'float'"  v-if="item[hitem].tdFloat "
						:style="(item[hitem].tdColspan ? 'width:' + item[hitem].tdColspan * 200 + 'px! important; display: inline-block! important; visibility: hidden; ' : 'display: inline-block! important; ')">
							<text>Look at me</text></view> Perform data processing here in generateMergeTable()// Traversal determines that the cell occupies two rows and takes it out of the document flow
			Object.keys(keyData).forEach(key= >{ 
				console.log(keyData[key].tdRowspan)
				if (keyData[key].tdRowspan * 1> =2) {
					keyData[key].tdFloat = true 				
Copy the code

And then you notice that the next row is also moving to the left and the reason for that is because the top one is merged, and the bottom one is going to have a placeholder of 0, and you’re going to use placeholder again, and I’ll show you some of thatInline code slice. GenerateMergeTable () is the same as tdColspan in the next row

if (i + 1 < tableLength) {
	/ / how many rows
	let firstTemp = this.packHeader[i + 1]
	/ / which columns
	firstTemp[key].tdColspan = keyData[key].tdColspan * 1
}
Copy the code

Original content, reprint must indicate the source.