1. 程式人生 > 程式設計 >vue實現滾動載入的表格

vue實現滾動載入的表格

實現效果

vue實現滾動載入的表格

碼雲地址

滾動載入知識儲備

參考ant-design-vue中list滾動載入的思路,使用vue-infinite-scroll加上vue-virtual-scroller作為解決方案。

元件封裝

因為整個系統使用的框架是ant-dsign-vue,所以元件封裝的變數命名風格儘可能的與a-table保持一致。

1. 元件命名

XScrollTable.vue

2. 提供的props

必填欄位:

dataSource -- 資料來源

columns -- 表格展示的列資訊,插槽用法和a-table不完全一樣,下面會提到。

itemSize -- 每行資料的高度

選填欄位:

rowKey -- 資料主鍵標識,預設為'key'

height -- 表格展示區域的高度,預設為500

pageSize -- 表格滾動每次滾動載入的資料量,預設為30

infiniteScrollDistance -- 表格觸發載入的距離條件,預設為10

rowSelection -- 表格多選配置,已處理的屬性有selectedRowKeys、onChange、width。預設為null,不展示多選。

3.使用舉例

首先初始化10000條資料,放在表格中進行顯示。

let data = new Array(10000).fill(1);

data = data.map((item1,index) => {
    let item = {};
    item.id = index;
    item.age = "姓名";
    item.address = "地址";
    return item;
});
export default data;

注意:這裡之所以加了fill(1),是因為通過Array建構函式產生的資料全是empty,沒有陣列索引,無法進行map迴圈。

載入表格

<x-scroll-table
                style="margin-top: 10px"
                row-key="id"
                :itemSize="22"
                :rowSelection="{selectedRowKeys: selectedRowKeys,onChange: onSelectChange,width:50}"
                :columns="columns"
                :dataSource="data">
            <template slot="action" slot-scope="{record,text}">
                <a @click="handleDetail(record)">詳情</a>
            </template>
        </x-scroll-table>

元件封裝總結

1.儘可能地使用computed計算屬性

雖然只是簡單地封裝了表格,但還是需要定義了很多的屬性,使用計算屬性代替在data裡定義變數,可以減少變數的維護工作量。

整個元件只定義了一個page變數,其它都是使用計算屬性的方式。

  data() {
    return {
      // 當前展示頁數
      page: 1,};
  },

舉個栗子:

通過page屬性定義一個計算屬性來表示當前已經載入的資料量

 // 展示的最大下標數量,存在比總資料條數多的情況,使用slice解決這個問題
    lastIndex() {
      return this.pageSize * this.page;
    },

通過這個計算屬性同時衍生出其他的計算屬性

// 表示表格資料是否已經載入完畢  
busy() {
      return this.lastIndex >= this.dataSource.length;
    },// 當前已經載入到RecycleScroller滾動元件的資料
    tableData() {
      return this.dataSource.slice(0,this.lastIndex);
    },

通過一個page屬性衍生出一系列的計算屬性,我只需要維護page屬性,其他都是自動計算的。

2.給表格提供插槽

首先通過表格傳入的columns引數,計算出需要渲染的列,這裡同樣使用計算屬性。

 // 將列陣列轉為列物件,將columnFieldKey值作為鍵,陣列項作為值
    columnMap() {
      return this.columns.reduce((returnValue,cur) => {
        returnValue[cur[columnFieldKey]] = cur;
        程式設計客棧return returnValue;
      },{});
    },// 取數組裡的列鍵值--columnFieldKey
    columnKeys() {
      return this.columns
          .map(item => item[columnFieldKey]);
    },

在template中遍歷

<div v-for="(key) of columnKeys"
             class="ellipsis-cell"
             :key="key"
             :style="itemStyle(columnMap[key])"
        >
          <slot v-if="izSlotRender(columnMap[key])"
                :name="columnMap[key].scopedSlots.customRender"
                :record="row"
                :text="row[key]">
          </slot>
          <span v-else :title="row[key]">{{ renderItem(row,index,key) }}</span>
        </div>

  // 是否使用插槽渲染
    izSlotRender(item) {
      return item.scopedSlots && item.scopedSlots.customRender;
    },

如果在定義columns時傳入了scopedSlots和customRender,將使用插槽渲染。

但是這裡存在和ant-design-vue中表格插槽渲染不一樣的地方。

我通過slot標籤定義的插槽,在父元件獲取插槽引數的時候,只能使用slot-scope="{record,text}"物件解構的方式。而ant-design-vue表格是可以直接使用slot-scope="record,text"獲取引數的。

另一種滾動載入資料的實現

table資料多的時候開啟頁面會載入一會才顯示資料,這樣體驗不好,所以要做滾動載入資料

<el-table :data="materielList" style="width: 100%" class="familyDataDetail" height="250">
<el-table-column prop="eventId" label="事件ID">
<template scope="scope">
<label>{{eventMap[scope.row.eventId] == null ? '--': eventMap[scope.row.eventId].sn}}</label>
</template>
</el-table-column>
<el-table-column prop="title" label="對應事件">
<template scope="scope">
<label>{{eventMap[scope.row.eventId] == null ? '--': eventMap[scope.row.eventId].title}}</label>
</template>
</el-table-column>
<el-table-column prop="age" label="負責人">
http://www.cppcns.com<template scope="scope">
<label>{{eventMap == null || eventMap[scope.row.eventId] == null || eventMap[scope.row.eventId].personalInformation == null ? '--':
&n程式設計客棧bsp;eventMap[scope.row.eventId].personalInformation.name}}</label>
</template>
</el-table-column>
<el-table-column prop="birthday" label="物料名稱">
<template scope="scope">
<label>{{materirlName}}</label>
 www.cppcns.com;</template>
</el-table-column>
<el-table-column prop="idcardNo" label="狀態">
<template scope="scope">
&nbsihipPCdp;<label>{{formatType(scope.row.type)}}</label>
</template>
</el-table-column>
<el-table-column prop="relationship" label="數量">
<template scope="scope">
<label>{{formatUseNum(scope.row.useNum)}}</label>
</template>
</el-table-column>
<el-table-column prop="ethtic" label="使用時間">
<template scope="scope">
<label>{{changeTime(scope.row.createOn)}}</label>
</template>
</el-table-column>
</el-table>

下面是js部分 

methods: {
init (param) {
  let id = param.param && param.param.id
  if(id){
      this.start = 0
MaterialRecordService.query({param: {baseId: this.baseId,materialId: id},start: this.start,limit: 30}).then(rsp => {//初次請求資料,30條
this.start += 30
this.materielList = rsp.data
MissionEventService.microList({ids: rsp.data.map(n => n.eventId)}).then(rsp3 => {
this.eventMap = {}
rsp3.data.forEach(n => (this.eventMap[n.id] = n))

})
})
  }
},onScroll() {
let inner = document.querySelector('.el-table__body-wrapper');
if(inner.scrollHeight - inner.scrollTop <= inner.clientHeight){//為true時證明已經到底,可以請求介面
if(this.flag){//設一個滾動事件的開關,(在data裡面宣告 flag: true)預設為true
this.flag = false
MaterialRecordService.query({param: {baseId: this.baseId,materialId: this.entity.id},limit:30}).then(rsp => {//每次載入30條
this.materielList = this.materielList.concat(rsp.data)
this.start += 30
this.flag = true
MissionEventService.microList({ids: rsp.data.map(n => n.eventId)}).then(rsp3 => {
rsp3.data.forEach(n => (this.eventMap[n.id] = n))
})
})
}
}
}
},mounted () {
this.init({...this.param})<br>    //監聽表格dom物件的滾動事件
document.querySelector('.el-table__body-wrapper').addEventListener('scroll',this.onScroll);
}

在這裡我要說明一下監聽的dom物件是哪一個

vue實現滾動載入的表格

我還要解釋下scrollHeight、scrollTop、clientHeight這三個屬性

vue實現滾動載入的表格

這是我截的別人的圖加了幾筆

scrollHeight:網頁正文全文高度,

scrollTop:網頁滾動的高度,

clientHeight:網頁可視區域的高度

以上就是vue實現滾動載入的表格的詳細內容,更多關於vue 滾動載入的表格的資料請關注我們其它相關文章!