共计 5420 个字符,预计需要花费 14 分钟才能阅读完成。
开发过程中,很多产品经理都喜爱做些花里胡哨的表格展现,以下是一种常见的表格展现形式,看上去如同很简单,实现起来很简略,上面看看代码怎么实现
组件实现次要围绕 vxe-talble-v3,这款基于 vue 的表格框架能节俭很大的功夫
template
<template>
<vxe-table
border
height="600"
:scroll-y="{enabled: false}"
:span-method="rowspanMethod"
:data="tableData"
align="center"
>
<vxe-column field="sort" width="150" title="序号"></vxe-column>
<vxe-column field="type" width="250" title="类型" :formatter="formatterType"> </vxe-column>
<vxe-colgroup title="验收我的项目" v-if="deepLevel>0">
<vxe-column v-for="(item,idx) in deepLevel" :key="idx" :field="`name${item}`" header-class-name="header"></vxe-column>
</vxe-colgroup>
<vxe-column field="content" type="html" width="350" title="设计规范要求及标准规定">
<template #default="{row}">
<div class="cellContent" v-if="XEUtils.isArray(row.content)">
<p @click="cellLink(item)" v-for="(item,idx) in row.content" :key="idx"><i class="el-icon-paperclip icon"></i><span class="link">{{item.provisions_info}}</span></p>
</div>
<span v-else>{{row.content}}</span>
</template>
</vxe-column>
</vxe-table>
</template>
js
import XEUtils from "xe-utils";
export default {data() {
return {tableData: [],
acceptance_item: [],
deepLevel:0,
XEUtils:XEUtils
};
},
created() {setTimeout(() => {
// 获取 api 数据
this.acceptance_item = this.getData();
this.acceptance_item.forEach((item,idx)=>{item.sort = idx+1+''})
let that = this;
// 遍历 api 树形构造层数,标记最深层
function arrLevel(arr,lv){if(!arr || !arr.length) return;
arr.forEach(item=>{
that.deepLevel = lv>that.deepLevel?lv:that.deepLevel;
if(item.children && item.children.length){arrLevel(item.children,lv+1)
}
})
}
// 标记最深层赋值,vxetable 在渲染进来
arrLevel(this.acceptance_item,1)
console.log(this.deepLevel)
this.toColTreeData(this.acceptance_item)
}, 2000);
},
methods: {
// 将一般树结构转换为横向树列表
toColTreeData(treeData) {const options = { children: "children"};
const list = [];
const keyMap = {};
XEUtils.eachTree(
treeData,
(item, index, result, paths, parent) => {
item, index, result, paths, parent;
keyMap[item.uid] = item;
item.keys = parent ? parent.keys.concat([item.uid]) : [item.uid];
if (!item.children || !item.children.length) {const row = {};
item.keys.forEach((key, index) => {
const level = index + 1;
const obj = keyMap[key];
row[`id${level}`] = obj.uid;
// 第 1 层赋值序号和类型
if(level==1){
row.sort = obj.sort
row.type = obj.type
}
// content 外面层会笼罩里面层
let content = obj.content?obj.content:obj.provisions
row.content = content;
// name 遍历整个构造的所有 name
row[`name${level}`] = obj.name
});
list.push(row);
}
},
options
);
this.keyMap = keyMap;
console.log(list)
this.tableData = list
},
formatterType ({cellValue}) {return cellValue==1?"主控我的项目": cellValue == 2? "个别我的项目":""},
cellLink(e){debugger},
// 通用行合并函数(将雷同多列数据合并为一行)rowspanMethod({row, _rowIndex, column,_columnIndex, visibleData}) {
let that = this;
let arr = []
for(let i=0;i<this.deepLevel;i++){arr.push(`name${i+1}`)
}
const fields =[...arr,...["type","sort"]];
const cellValue = row[column.property];
if (cellValue && fields.includes(column.property)) {const prevRow = visibleData[_rowIndex - 1];
let nextRow = visibleData[_rowIndex + 1];
if (prevRow && prevRow[column.property] === cellValue) {return { rowspan: 0, colspan: 0};
} else {
let countRowspan = 1;
while (nextRow && nextRow[column.property] === cellValue) {nextRow = visibleData[++countRowspan + _rowIndex];
}
if (countRowspan > 1) {return { rowspan: countRowspan, colspan: 1};
}
}
}
// 用 point 标记 name+'n'
let point = ''
Object.keys(row).forEach(item=>{if(item.indexOf('name')>-1 && item != `name${that.deepLevel}`){point = item;}
})
// point 与 column.property 相等时,操作以后单元格横移拉伸
if(point == column.property && !row[`name${that.deepLevel}`]){return { rowspan: 1, colspan: this.deepLevel - ( parseInt(point.split('name')[1]) - 1 ) }
}
// 将 undefined 的单元格暗藏
if(cellValue==undefined){return { rowspan: 0, colspan: 0}
}
},
getData(){
const data = [{
id: 10,
uid: "317218091849220096",
puid: "0",
type: 1,
name: "1",
content: "钢筋",
provisions: [
{
provisions_id: "",
provisions_info: "",
specification_id: "",
},
],
children: [
{
id: 9,
uid: "317218091849220097",
puid: "317218091849220096",
type: 0,
name: "1.1",
content: "",
provisions: [
{
provisions_id: "1",
provisions_info: "钢筋",
specification_id: "1",
},
{
provisions_id: "2",
provisions_info: "混凝土",
specification_id: "1",
},
],
children: [],},
{
id: 9,
uid: "317218091849220200",
puid: "317218091849220096",
type: 0,
name: "1.2",
content: "",
provisions: [
{
provisions_id: "3",
provisions_info: "钢筋 1",
specification_id: "1",
},
{
provisions_id: "4",
provisions_info: "混凝土 1",
specification_id: "1",
},
],
children: [],},
{
id: 10,
uid: "317218091849220201",
puid: "317218091849220096",
type: 0,
name: "1.3",
content: "",
provisions: [
{
provisions_id: "5",
provisions_info: "钢筋 2",
specification_id: "1",
},
{
provisions_id: "6",
provisions_info: "混凝土 2",
specification_id: "1",
},
],
children: [
// {
// id: 11,
// uid: "317218091849220202",
// puid: "317218091849220201",
// type: 0,
// name: "1.3.1",
// content: "个别 323",
// provisions: [
// {
// provisions_id: "",
// provisions_info: "",
// specification_id: "",
// },
// ],
// children: [],
// },
],
},
],
},
{
id: 13,
uid: "317218091849220098",
puid: "0",
type: 2,
name: "2",
content: "",
provisions: [
{
provisions_id: "",
provisions_info: "",
specification_id: "",
},
],
children: [
{
id: 12,
uid: "317218091849220099",
puid: "317218091849220098",
type: 0,
name: "2.1",
content: "",
provisions: [
{
provisions_id: "",
provisions_info: "",
specification_id: "",
},
],
children: [
{
id: 11,
uid: "317218091849220100",
puid: "317218091849220099",
type: 0,
name: "2.1.1",
content: "个别",
provisions: [
{
provisions_id: "",
provisions_info: "",
specification_id: "",
},
],
children: [],},
{
id: 11,
uid: "317218091849220101",
puid: "317218091849220099",
type: 0,
name: "2.1.2",
content: "个别",
provisions: [
{
provisions_id: "",
provisions_info: "",
specification_id: "",
},
],
children: [],},
],
},
],
}]
return data
}
},
};
scss
.vxe-table{
// 暗藏空表头
&::v-deep .header {display: none;}
&::v-deep .cellContent {
.link{
border-bottom: 1px solid #7ca8fb;
color: #7ca8fb;
cursor: pointer;
margin-left: 5px;
&:hover{
border-bottom: 1px solid blue;
color: blue;
}
}
}
}
正文完