vue開發(fā)table數(shù)據(jù)合并實(shí)現(xiàn)詳解
前言
項(xiàng)目中的某個(gè)模塊,一個(gè)勾選表格數(shù)據(jù),里面的行數(shù)據(jù)由于有關(guān)聯(lián)關(guān)系,需要多行數(shù)據(jù)合并,然后勾選時(shí)選中一條數(shù)據(jù),方便進(jìn)行下一步業(yè)務(wù)操作,然后產(chǎn)品經(jīng)理就指著原型上的表格,說(shuō):這里,這里, 數(shù)據(jù)需要合并......
功能需求有了,里面有個(gè)技術(shù)實(shí)現(xiàn)點(diǎn) —— 表格數(shù)據(jù)合并,下面我們就來(lái)分析一下這個(gè)表格數(shù)據(jù)合并的實(shí)現(xiàn)
思路梳理
方案一 Element 官方 Table 組件數(shù)據(jù)合并
由于項(xiàng)目用的 Element UI 庫(kù), Table 表格 組件剛好有現(xiàn)成的功能,官方還提供了 Demo,代碼復(fù)制過(guò)來(lái)直接改一下放到項(xiàng)目,這不還簡(jiǎn)單
直接翻到 Element UI Table 組件數(shù)據(jù)合并位置看官方案例,發(fā)現(xiàn)里面用了一個(gè) span-method 屬性
| span-method | 合并行或列的計(jì)算方法 | Function({ row, column, rowIndex, columnIndex }) | — | — |
|---|
通過(guò)如下方式處理合并行或者列
<el-table
border
ref="multipleTable"
:data="tableData"
tooltip-effect="dark"
style="width: 800px; margin: 10px 0"
@selection-change="handleSelectionChange"
:span-method="objectSpanMethod"
></table>
methods: {
objectSpanMethod ({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 0) {
if (rowIndex % 2 === 0) {
return {
rowspan: 2,
colspan: 1
}
} else {
return {
rowspan: 0,
colspan: 0
}
}
}
}
}
通過(guò)這個(gè)函數(shù)控制 rowspan colspan 來(lái)實(shí)現(xiàn)合并,但是分析數(shù)據(jù)結(jié)構(gòu)的時(shí)候發(fā)現(xiàn)兩個(gè)點(diǎn)
- 這種方案的數(shù)據(jù)是多條數(shù)據(jù)合并成一行渲染的方式
- 多行數(shù)據(jù)合并后,選中行的效果還是一行一行的,不同行的選中效果不一樣

實(shí)際項(xiàng)目中數(shù)據(jù)格式是這樣的,表格行有對(duì)應(yīng)的ID,每行數(shù)據(jù)超過(guò)20列,每列內(nèi)容部分可能還比較多,如下例子
[
{
id: '1',
date: '2016-05-03',
name: '張三',
address: '家庭地址:上海市普陀區(qū)金沙江路'
},
{
id: '1',
date: '2016-05-03',
name: '張三',
address: '公司地址:北京市朝陽(yáng)區(qū)金臺(tái)路'
},
{
id: '2',
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀區(qū)金沙江路 1518 '
}
]
按照這種方式的話,每次請(qǐng)求后端都需要返回大量數(shù)據(jù),性能不是很好;不同的列字段還需要?jiǎng)討B(tài)處理表格單元格的合并, span-method 里面的邏輯得寫一大坨, 這個(gè)表格合并方案在當(dāng)前項(xiàng)目中用不是很友好
注意
Demo 里面的是靜態(tài)數(shù)據(jù),如果是動(dòng)態(tài)比較id的合并的方式, span-method 里面邏輯需要單獨(dú)處理。網(wǎng)上有很多動(dòng)態(tài)對(duì)比ID數(shù)據(jù)實(shí)現(xiàn)數(shù)據(jù)行合并的實(shí)現(xiàn),按需搜索即可,文章下面也提供了兩個(gè)實(shí)現(xiàn)參考鏈接
那還有更好的實(shí)現(xiàn)方案嗎?
方案二 Table-column Scoped Slot
首先要滿足合并行是一條數(shù)據(jù),需要多行展示的數(shù)據(jù)通過(guò) Table-column Slot 實(shí)現(xiàn),寫個(gè)循環(huán)動(dòng)態(tài)展示數(shù)據(jù),如下數(shù)據(jù)格式
[
{
id: '1',
date: '2016-05-03',
name: '張三',
address: ['家庭地址:上海市普陀區(qū)金沙江路', '公司地址:北京市朝陽(yáng)區(qū)金臺(tái)路']
},
{
id: '2',
date: '2016-05-02',
name: '王小虎',
address: ['上海市普陀區(qū)金沙江路 1518 ']
},
{
id: '3',
date: '2016-05-02',
name: '李四',
address: ['廣州市xxx區(qū)']
}
]
例如需要多行展示的列為 address, 后端返回的格式為一個(gè)數(shù)組直接遍歷使用 div 渲染
<el-table-column
label="地址"
>
<template slot-scope="scope">
<div
style=""
v-for="(item, index) in scope.row.address"
:key="index"
>
{{ item }}
</div>
</template>
</el-table-column>
得到如下效果

這時(shí)候并不是一個(gè)多行數(shù)據(jù)合并的效果,給 div 加個(gè) border-bottom 樣式,順便處理一下渲染時(shí)的最后一個(gè) div不加 border
<el-table-column
label="地址"
class-name="cell-control-type"
label-class-name="cell-control-title"
>
<template slot-scope="scope">
<div
style=""
v-for="(item, index) in scope.row.address"
:key="index"
>
<div
v-if="index === scope.row.address.length - 1"
style=""
>
{{ item }}
</div>
<div
v-else
style="border-bottom: 1px solid #ebeef5;"
>
{{ item }}
</div>
</div>
</template>
</el-table-column>

這時(shí)候的表格列有邊距問(wèn)題,看起來(lái)還不是一個(gè)合并的表格行,接下來(lái)我們看下表格內(nèi)置的邊距控制

通過(guò)分析 Table 的源碼,需要把對(duì)應(yīng)的列的內(nèi)置 padding 屬性去掉,然后讓循環(huán)遍歷數(shù)據(jù)的 div 寬度充滿表格單元格,這時(shí)候再給循環(huán)遍歷的 div 添加對(duì)應(yīng)的邊距,去除 Element Table 內(nèi)置 cell 樣式的時(shí)候再對(duì)應(yīng)的列上添加了一個(gè)自定義 class 類 —— cell-control-type,這里用來(lái)修改 address 當(dāng)前列的樣式,而不影響其他列
由于移除整個(gè)列的 padding, 列頭標(biāo)題位置也受影響了,使用 label-class-name 屬性把列 title 的 margin-left 設(shè)置一下,就和原生效果一樣了
<el-table-column
label="地址"
class-name="cell-control-type"
label-class-name="cell-control-title"
>
<template slot-scope="scope">
<div
style=""
v-for="(item, index) in scope.row.address"
:key="index"
>
<div
v-if="index === scope.row.address.length - 1"
style="padding: 10px"
>
{{ item }}
</div>
<div
v-else
style="border-bottom: 1px solid #ebeef5; padding: 10px"
>
{{ item }}
</div>
</div>
</template>
</el-table-column>
<style>
.cell-control-type {
padding: 0 0 !important;
}
.cell-control-title {
margin-left: 10px;
}
.cell-control-type .cell {
padding: 0 0 !important;
}
</style>
看一下調(diào)整后的完整效果,這時(shí)候看起來(lái)合并效果還不錯(cuò),也滿足產(chǎn)品經(jīng)理的需求了

注意
修改 Element 原生樣式的時(shí)候需要寫到全局 <style> 中,否則樣式修改無(wú)效
修改UI庫(kù)組件源碼的時(shí)候需要注意當(dāng)前的樣式修改是否影響了其他 .vue 頁(yè)面的實(shí)現(xiàn)效果,尤其公共組件統(tǒng)一修改的時(shí)候
小技巧
可以通過(guò)給需要修改的組件添加個(gè)一個(gè)自定義的 class 類,例如修改 Table 組件可以如下寫法
.custom-class .table {}
參考鏈接
Element UI Table 合并行或列
Element UI Table 動(dòng)態(tài)合并行或列
http://www.dbjr.com.cn/article/256955.htm
http://www.dbjr.com.cn/article/256947.htm
代碼地址
以上就是vue開發(fā)table數(shù)據(jù)合并實(shí)現(xiàn)詳解的詳細(xì)內(nèi)容,更多關(guān)于vue開發(fā)table數(shù)據(jù)合并的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue Draggable實(shí)現(xiàn)拖動(dòng)改變順序
這篇文章主要為大家詳細(xì)介紹了vue Draggable實(shí)現(xiàn)拖動(dòng)改變順序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04
vue實(shí)現(xiàn)簡(jiǎn)單轉(zhuǎn)盤抽獎(jiǎng)功能
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)簡(jiǎn)單轉(zhuǎn)盤抽獎(jiǎng)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
vue路由守衛(wèi),限制前端頁(yè)面訪問(wèn)權(quán)限的例子
今天小編就為大家分享一篇vue路由守衛(wèi),限制前端頁(yè)面訪問(wèn)權(quán)限的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-11-11
vue+el使用this.$confirm,不能阻斷代碼往下執(zhí)行的解決
這篇文章主要介紹了vue+el使用this.$confirm,不能阻斷代碼往下執(zhí)行的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09
vue跳轉(zhuǎn)同一個(gè)組件,參數(shù)不同,頁(yè)面接收值只接收一次的解決方法
今天小編就為大家分享一篇vue跳轉(zhuǎn)同一個(gè)組件,參數(shù)不同,頁(yè)面接收值只接收一次的解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-11-11

