vue實(shí)現(xiàn)滾動加載的表格
實(shí)現(xiàn)效果
滾動加載知識儲備
參考ant-design-vue中l(wèi)ist滾動加載的思路,使用vue-infinite-scroll加上vue-virtual-scroller作為解決方案。
組件封裝
因?yàn)檎麄€系統(tǒng)使用的框架是ant-dsign-vue,所以組件封裝的變量命名風(fēng)格盡可能的與a-table保持一致。
1. 組件命名
XScrollTable.vue
2. 提供的props
必填字段:
dataSource -- 數(shù)據(jù)源
columns -- 表格展示的列信息,插槽用法和a-table不完全一樣,下面會提到。
itemSize -- 每行數(shù)據(jù)的高度
選填字段:
rowKey -- 數(shù)據(jù)主鍵標(biāo)識,默認(rèn)為'key'
height -- 表格展示區(qū)域的高度,默認(rèn)為500
pageSize -- 表格滾動每次滾動加載的數(shù)據(jù)量,默認(rèn)為30
infiniteScrollDistance -- 表格觸發(fā)加載的距離條件,默認(rèn)為10
rowSelection -- 表格多選配置,已處理的屬性有selectedRowKeys、onChange、width。默認(rèn)為null,不展示多選。
3.使用舉例
首先初始化10000條數(shù)據(jù),放在表格中進(jìn)行顯示。
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),是因?yàn)橥ㄟ^Array構(gòu)造函數(shù)產(chǎn)生的數(shù)據(jù)全是empty,沒有數(shù)組索引,無法進(jìn)行map循環(huán)。
加載表格
<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>
組件封裝總結(jié)
1.盡可能地使用computed計(jì)算屬性
雖然只是簡單地封裝了表格,但還是需要定義了很多的屬性,使用計(jì)算屬性代替在data里定義變量,可以減少變量的維護(hù)工作量。
整個組件只定義了一個page變量,其它都是使用計(jì)算屬性的方式。
data() { return { // 當(dāng)前展示頁數(shù) page: 1, }; },
舉個栗子:
通過page屬性定義一個計(jì)算屬性來表示當(dāng)前已經(jīng)加載的數(shù)據(jù)量
// 展示的最大下標(biāo)數(shù)量,存在比總數(shù)據(jù)條數(shù)多的情況,使用slice解決這個問題 lastIndex() { return this.pageSize * this.page; },
通過這個計(jì)算屬性同時(shí)衍生出其他的計(jì)算屬性
// 表示表格數(shù)據(jù)是否已經(jīng)加載完畢 busy() { return this.lastIndex >= this.dataSource.length; }, // 當(dāng)前已經(jīng)加載到RecycleScroller滾動組件的數(shù)據(jù) tableData() { return this.dataSource.slice(0, this.lastIndex); },
通過一個page屬性衍生出一系列的計(jì)算屬性,我只需要維護(hù)page屬性,其他都是自動計(jì)算的。
2.給表格提供插槽
首先通過表格傳入的columns參數(shù),計(jì)算出需要渲染的列,這里同樣使用計(jì)算屬性。
// 將列數(shù)組轉(zhuǎn)為列對象,將columnFieldKey值作為鍵,數(shù)組項(xiàng)作為值 columnMap() { return this.columns.reduce((returnValue, cur) => { returnValue[cur[columnFieldKey]] = cur; return returnValue; }, {}); }, // 取數(shù)組里的列鍵值--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時(shí)傳入了scopedSlots和customRender,將使用插槽渲染。
但是這里存在和ant-design-vue中表格插槽渲染不一樣的地方。
我通過slot標(biāo)簽定義的插槽,在父組件獲取插槽參數(shù)的時(shí)候,只能使用slot-scope="{record,text}"對象解構(gòu)的方式。而ant-design-vue表格是可以直接使用slot-scope="record,text"獲取參數(shù)的。
另一種滾動加載數(shù)據(jù)的實(shí)現(xiàn)
table數(shù)據(jù)多的時(shí)候打開頁面會加載一會才顯示數(shù)據(jù),這樣體驗(yàn)不好,所以要做滾動加載數(shù)據(jù)
<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="對應(yīng)事件"> <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="負(fù)責(zé)人"> <template scope="scope"> <label>{{eventMap == null || eventMap[scope.row.eventId] == null || eventMap[scope.row.eventId].personalInformation == null ? '--': eventMap[scope.row.eventId].personalInformation.name}}</label> </template> </el-table-column> <el-table-column prop="birthday" label="物料名稱"> <template scope="scope"> <label>{{materirlName}}</label> </template> </el-table-column> <el-table-column prop="idcardNo" label="狀態(tài)"> <template scope="scope"> <label>{{formatType(scope.row.type)}}</label> </template> </el-table-column> <el-table-column prop="relationship" label="數(shù)量"> <template scope="scope"> <label>{{formatUseNum(scope.row.useNum)}}</label> </template> </el-table-column> <el-table-column prop="ethtic" label="使用時(shí)間"> <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 => {//初次請求數(shù)據(jù),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時(shí)證明已經(jīng)到底,可以請求接口 if(this.flag){//設(shè)一個滾動事件的開關(guān),(在data里面聲明 flag: true)默認(rèn)為true this.flag = false MaterialRecordService.query({param: {baseId: this.baseId, materialId: this.entity.id},start: this.start,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> //監(jiān)聽表格dom對象的滾動事件 document.querySelector('.el-table__body-wrapper').addEventListener('scroll', this.onScroll); }
在這里我要說明一下監(jiān)聽的dom對象是哪一個
我還要解釋下scrollHeight、scrollTop、clientHeight這三個屬性
這是我截的別人的圖加了幾筆
scrollHeight:網(wǎng)頁正文全文高度,
scrollTop:網(wǎng)頁滾動的高度,
clientHeight:網(wǎng)頁可視區(qū)域的高度
以上就是vue實(shí)現(xiàn)滾動加載的表格的詳細(xì)內(nèi)容,更多關(guān)于vue 滾動加載的表格的資料請關(guān)注腳本之家其它相關(guān)文章!
- Vue 無限滾動加載指令實(shí)現(xiàn)方法
- Vue.js 的移動端組件庫mint-ui實(shí)現(xiàn)無限滾動加載更多的方法
- Vue實(shí)現(xiàn)下拉滾動加載數(shù)據(jù)的示例
- 通過原生vue添加滾動加載更多功能
- vue 使用鼠標(biāo)滾動加載數(shù)據(jù)的例子
- vue指令做滾動加載和監(jiān)聽等
- 簡單方法實(shí)現(xiàn)Vue?無限滾動組件示例
- 基于Vue3實(shí)現(xiàn)無限滾動組件的示例代碼
- 手寫vue無限滾動指令的詳細(xì)過程
- 基于Vue實(shí)現(xiàn)卡片無限滾動動畫
- Vue中實(shí)現(xiàn)滾動加載與無限滾動
相關(guān)文章
vue實(shí)現(xiàn)的網(wǎng)易云音樂在線播放和下載功能案例
這篇文章主要介紹了vue實(shí)現(xiàn)的網(wǎng)易云音樂在線播放和下載功能,結(jié)合具體實(shí)例形式分析了網(wǎng)易云音樂相關(guān)接口調(diào)用與操作技巧,需要的朋友可以參考下2019-02-02vue實(shí)現(xiàn)一拉到底的滑動驗(yàn)證
這篇文章主要為大家詳細(xì)介紹了vue簡單的一拉到底的滑動驗(yàn)證,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07前端單獨(dú)實(shí)現(xiàn)vue動態(tài)路由的示例代碼
Vue動態(tài)路由權(quán)限涉及根據(jù)用戶權(quán)限動態(tài)生成路由配置,實(shí)現(xiàn)此功能可增強(qiáng)應(yīng)用安全性、靈活性,提升用戶體驗(yàn)和開發(fā)效率,本文就來介紹一下前端單獨(dú)實(shí)現(xiàn)vue動態(tài)路由的示例代碼,感興趣的可以了解一下2024-09-09vue 實(shí)現(xiàn)Web端的定位功能 獲取經(jīng)緯度
這篇文章主要介紹了vue 實(shí)現(xiàn)Web端的定位功能獲取經(jīng)緯度,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-08-08vue.js在標(biāo)簽屬性中插入變量參數(shù)的方法
這篇文章主要介紹了vue.js在標(biāo)簽屬性中插入變量參數(shù)的方法,非常不錯,具有參考借鑒價(jià)值,需要的朋友可以參考下2018-03-03vue關(guān)于錨點(diǎn)定位、跳轉(zhuǎn)到指定位置實(shí)現(xiàn)方式
這篇文章主要介紹了vue關(guān)于錨點(diǎn)定位、跳轉(zhuǎn)到指定位置實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-04-04