簡體   English   中英

如何生成每行有 3 列的表

[英]How to generating table that will have 3 columns per row

我使用 Vue 2。

我從集合中生成表:

  <table class="table table-striped table-bordered">
      <tbody>
        <tr v-for="(type, typeIndex) in getAllUpgradeTypes" :key="typeIndex">
          <td>
            <imageDesc
              style="margin-left: 10px"
              :title="type"
              :text="'Select an Option'"
              :zoneId="selectedZone.id"
            />
          </td>
        </tr>
      </tbody>
    </table>
    

目前,創建的表是多行的,每行只有一列,並且在列內顯示一項。

我的問題是如何生成每行包含 3 列的表?

您至少可以使用幾種不同的模式。 一種涉及在模板中迭代數據之前重新排列數據,另一種則不需要。 我會告訴你兩個。

在這兩種情況下,都使用數據屬性來保存列數:

data: () => ({
  numCols: 3
})

將數據重新組織成二維數組

而不是一個包含所有項目的數組,而是使用計算將數據重新組織成一個多維的行和列數組:

computed: {
  arrangedData() {
    const arrangedData = [];
    this.getAllUpgradeTypes.forEach((item, index) => {
      if (index % this.numCols === 0) {
        arrangedData.push([])
      }
      arrangedData[arrangedData.length - 1].push(item);
    });
    return arrangedData;
  }
}

像這樣迭代數據:

<table class="table table-striped table-bordered">
  <tr v-for="(row, rowIndex) in arrangedData" :key="rowIndex">
    <td v-for="(type, typeIndex) in row" :key="`${rowIndex}:${typeIndex}`">
      {{ type }}
    </td>
  </tr>
</table>

這是一個演示:

 new Vue({ el: "#app", data: () => ({ getAllUpgradeTypes: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'], numCols: 3 }), computed: { arrangedData() { const arrangedData = []; this.getAllUpgradeTypes.forEach((item, index) => { if (index % this.numCols === 0) { arrangedData.push([]) } arrangedData[arrangedData.length - 1].push(item); }); return arrangedData; } } });
 td { width: 40px }
 <div id="app"> <table class="table table-striped table-bordered"> <tr v-for="(row, rowIndex) in arrangedData":key="rowIndex"> <td v-for="(type, typeIndex) in row":key="`${rowIndex}:${typeIndex}`"> {{ type }} </td> </tr> </table> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

-或者-

計算行數

另一種方法涉及使用計算來計算行數。 它的代碼更少,但是type在模板中得到了一個丑陋的語法:

computed: {
  numRows() {
    return Math.ceil(this.getAllUpgradeTypes.length / this.numCols);
  }
}

像這樣迭代數據:

<table class="table table-striped table-bordered">
  <tr v-for="(row, indexRow) in numRows">
    <td v-for="(col, indexCol) in numCols">
      {{ getAllUpgradeTypes[(indexRow * numCols) + indexCol] }}
    </td>
  </tr>
</table>

這是一個演示:

 new Vue({ el: "#app", data: () => ({ getAllUpgradeTypes: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'], numCols: 3 }), computed: { numRows() { return Math.ceil(this.getAllUpgradeTypes.length / this.numCols); } } });
 td { width: 40px; }
 <div id="app"> <table> <tr v-for="(row, indexRow) in numRows":key="indexRow"> <td v-for="(type, indexCol) in numCols":key="`${rowIndex}:${typeIndex}`"> {{ getAllUpgradeTypes[(indexRow * numCols) + indexCol] }} </td> </tr> </table> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

這些選項可能有一些變化,但我認為第一個可能是模板清晰度的最佳選擇。

這是我對類似問題的解決方案。 我需要生成一個可打印的頁面並從我們數據庫中的表中顯示信息。 頁面的外觀要求我每行有 3 個固定大小的行和 3 個固定大小的列。

我添加了樣式以使其具有類似網格的外觀,但這是我在 3 行后生成帶有分頁符的表格的方式:

這是我在 HTML (cshtml) 文件中設置表的地方:

<table id="employee-table" class="m-auto">

</table>

這是我的 JavaScript function,它位於外部 JS 文件中(如果您是這樣設置的,請不要忘記在 HTML 中引用該文件)

function GeneratePrintablePDF(employeeData) {
    document.getElementById('loader').classList.add('hidden'); //this is just the "loading" spinner for when the page is loading
    dataContainer = document.getElementById('employee-table');

    numberOfRows = employeeData.length / 3;

    if (employeeData % 3 != 0) {
        numberOfRows = Math.trunc(numberOfRows);
        numberOfRows += 1;
    } 

    var emp = 0;

    do
    {
        for (var row = 1; row <= numberOfRows; row++) {
            var tableRowDiv = document.createElement('div');
            dataContainer.appendChild(tableRowDiv);

            var tableRow = document.createElement('tr');
            tableRowDiv.appendChild(tableRow);

            for (var col = 1; col < 4; col++)
            {
                if (emp < employeeData.length) {
                    var tableCol = document.createElement('td');
                    tableCol.className = 'pdf-employee-box';
                    tableRow.appendChild(tableCol);

                    var empName = document.createElement('div');
                    empName.className = 'fw-bold';
                    empName.innerHTML = `${employeeData[emp].firstName} ${employeeData[emp].lastName}`;
                    tableCol.appendChild(empName);

                    var empPhoto = document.createElement('img');

                    var employeePhotoUrl = employeeData[emp].azurePhotoURL;
                    if (employeePhotoUrl == null) {
                        empPhoto.src = '/Images/lg_unavailable.jpg';
                    } else {
                        empPhoto.src = employeePhotoUrl;
                    }

                    var empPhotoOnError = document.createAttribute('onerror');
                    empPhotoOnError.value = "this.onerror=null;this.src='/Images/lg_unavailable.jpg';";
                    empPhoto.setAttributeNode(empPhotoOnError);

                    empPhoto.alt = 'Employee Photo';
                    empPhoto.className = 'employee-photo-pdf pdf-image';
                    tableCol.appendChild(empPhoto);

                    var empTitle = document.createElement('div');
                    empTitle.innerHTML = employeeData[emp].title != null ? `Title: ${employeeData[emp].title}` : 'Title: Unknown';
                    empTitle.className = 'pdf-details';
                    tableCol.appendChild(empTitle);

                    var empDept = document.createElement('div');
                    empDept.innerHTML = employeeData[emp].department != null ? `Department: ${employeeData[emp].department}` : 'Department: Unknown';
                    empDept.className = 'pdf-details';
                    tableCol.appendChild(empDept);

                    var empEmail = document.createElement('div');
                    empEmail.innerHTML = (employeeData[emp].emailAddress != null && !employeeData[emp].emailAddress.toLowerCase().includes('no ')) ? `Email: ${employeeData[emp].emailAddress}` : 'Email: Unknown/None';
                    empEmail.className = 'pdf-details';
                    tableCol.appendChild(empEmail);

                    var empStartDate = document.createElement('div');
                    empStartDate.innerHTML = employeeData[emp].startDate != null ? `Start Date: ${employeeData[emp].startDate}` : 'Start Date: Unknown';
                    empStartDate.className = 'pdf-details';
                    tableCol.appendChild(empStartDate);

                    var empLocation = document.createElement('div');
                    empLocation.innerHTML = employeeData[emp].location != null ? `Location: ${employeeData[emp].location}` : 'Location: Unknown';
                    empLocation.className = 'pdf-details';
                    tableCol.appendChild(empLocation);

                    if (col == 2) tableCol.className = tableCol.className + ' pdf-grid-lines';

                    emp++;
                }  
            }

            if (emp % 9 == 0) {
                tableRowDiv.className += 'page-break-after';
            }
        }
    } while (emp < employeeData.length)
    
    
}

我決定根據我們有多少員工記錄來計算我需要的行數。 所以,如果我們有 436 名員工,那么我確定我需要 146 行。 所以我正在對其進行編程以生成我需要的精確行數,並且每行只放置 3 個項目(列)。 在這種情況下,第 146 行只有 1 條記錄。

如您所見,我的循環中的代碼僅在到達最后一個員工之前運行,因此它不會引發索引超出范圍異常。

這個特定的代碼是我告訴表格跳到下一頁的地方,這樣員工記錄就不會跑到另一個頁面上並拆分信息。

if (emp % 9 == 0) {
   tableRowDiv.className += 'page-break-after';
}

這是我在外部 CSS 文件中引用的 CSS:

@media print {
    .page-break-after {
        break-after: page;
    }
}

我知道我絕不是最終的編程大師,所以可能有更好或更簡單的方法來做到這一點。 然而,這就是我如何讓它在我的環境中工作的方式,它在不使用某些框架或庫的情況下完成了我需要它做的事情。

我在研究中發現許多 PDF 生成器框架、庫等現在都需要許可。 因此,如果生成可打印的文檔是您的目標,那么這也適用於您。 無論如何,祝你好運,我希望我幫助了某人。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM