一、首先看看需求最终效果图,该需求总共罗列以下几点
- 最左侧采用树状结构将地址省市区县街道展示出来,并且控制名称长度限制,多余的用省略号表示,鼠标悬浮上去名称展示出来
- 列表默认展示市一级数据,县及街道数据都是点击+按钮,通过ajax向后台请求获得
- 该页面做了前端数据优化处理,地区数据是后端一次性返回的,所以页面渲染会很卡,前端采用监听滚动条事件实行数据分页解决卡死问题
- 表头日期也是后端动态获得,其中,列表中当前核销量列数据的显隐是根据是否为医保专用合作商数据控制的,选择是查询,当前核销量字段会显示,否则,该列消失,具体情况看下面代码
二、表格数据html及css部分
.adressTable .ivu-table-cell {
display: flex;
justify-content: center;
align-items: center;
padding: 0!important;
}
.ivu-table th.test-name {
background: #1b90f0;
color: #fff;
text-align: center;
font-size: 12px!important;
}
table td{
padding: 0!important;
}
.dataTabList {
width: 100px;
height: 30px;
display: flex;
margin-right: 35px;
background: #e4ebf0;
}
.dataTabList .dataTabli {
width: 50px;
height: 30px;
font-size: 14px;
border: 1px solid #999;
color: #666;
line-height: 30px;
text-align: center;
background: #fff;
cursor: pointer;
}
.dataTabList .dataTabActive {
background: #1b90f0;
color: #fff;
}
<Card :bordered="false" style="margin-bottom:20px;">
<i-form :model="formInline" ref="formInline" inline :label-width="70">
<Row style="margin-bottom: 20px">
<i-col span="8">
<Form-Item label="是否为医保专用合作商数据:" style="width:100%;"
prop="isMedicalPay" :label-width="165">
<Radio-Group v-model="formInline.isMedicalPay">
<Radio label="1">是</Radio>
<Radio label="0">否</Radio>
</Radio-Group>
</Form-Item>
</i-col>
<i-col span="2" offset="14">
<i-button type="primary" style="width:100%;"@click="getList(1,true);currentPage=1;" :loading="searchFlag">查询</i-button>
</i-col>
</Row>
</i-form>
</Card>
<Card :bordered="false" :padding="20">
<p slot="title" style="font-size: 16px;color: #333">地区数据列表</p>
<div slot="extra" style="display: flex;align-items: center">
<div class="dataTabList">
<div class="dataTabli"
v-for="(item,index) in dataTabList"
:key="index"
:class="{dataTabActive:dataTabNum==item.value}"
@click="signDataTable(item.value)"
>{{item.label}}</div>
</div>
<i-button type="primary" slot="extra" class="daoBtnStyls"
@click="updateModel=true">导出</i-button>
</div>
<i-Table row-key="name" update-show-children :max-height="tableHeight" :load-data="handleLoadData" :loading="loading" :columns="tabelHeard" :data="tableBodyList" border class="adressTable"></i-Table>
</Card>
三、vue代码及方法
data: function() {
return{
dataTabList:[
{
value:'1',
label:'省'
},
{
value:'2',
label:'市'
}
],
dataTabNum:2,
tabelHeard: [],
tableBodyList: [],
addressList:[],
formInline:{
date:'2021-02-01',
province:'',
city:'',
isMedicalPay:'1'
},
searchFlag:false,
detailDataListAll:[],
detailPageSize:6,
detailTotal:0,
pageIndex:1,
totalPage:1,
tableHeight: 500,
loading: false,
}
},
mounted:function(){
var _this = this
_this.getList(1);
_this.$nextTick(() => {
var tableScrol = document.getElementsByClassName('ivu-table-body')[0]
tableScrol.addEventListener("scroll", (v) => {
var scrollDistance = tableScrol.scrollHeight - tableScrol.scrollTop - tableScrol.clientHeight;
if (scrollDistance <= 0) {
if (_this.pageIndex >= _this.totalPage) {
_this.$Message.error('还滑,我已经到底了!!!')
}
if (_this.pageIndex < _this.totalPage) {
_this.pageIndex++;
_this.changepage(_this.pageIndex)
}
}
});
})
},
methods: {
changepage:function(index) {
var _this=this;
var _start = (index - 1) * _this.detailPageSize;
var _end = index * _this.detailPageSize;
var newList = _this.detailDataListAll.slice(_start, _end);
if(_this.dataTabNum==2){
newList.forEach(function (item) {
item._showChildren = true
})
}else{
newList.forEach(function (item) {
item._showChildren = false
})
}
for(var i of newList){
_this.tableBodyList.push(i)
}
var set = new Set(_this.tableBodyList);
_this.tableBodyList = Array.from(set)
},
signDataTable:function(value){
var _this = this;
_this.dataTabNum = value;
_this.pageIndex = 1
if(_this.dataTabNum==2){
_this.detailPageSize = 6
_this.tableHeight = 500
}else{
_this.detailPageSize = 10
_this.tableHeight = 350
}
_this.totalPage = _this.detailTotal/_this.detailPageSize
if (_this.detailTotal < _this.detailPageSize) {
_this.tableBodyList = _this.detailDataListAll;
} else {
_this.tableBodyList = _this.detailDataListAll.slice(0, _this.detailPageSize);
}
_this.getPackageData()
},
getPackageData:function(){
var _this = this;
if(_this.dataTabNum==2){
_this.tableBodyList.forEach(function (item) {
item._showChildren = true
})
}else{
_this.tableBodyList.forEach(function (item) {
item._showChildren = false
})
}
_this.tableBodyList.forEach(function (item) {
if(item.name=='无'){
delete item._showChildren;
delete item._loading;
}
})
var isYibao;
var noYibao;
isYibao = [
{
title: '省市区',
key: 'name',
tree: true,
width: 220,
className: 'test-name',
render: (h, params) => {
let self = this
return h('div',{
style:{
height:'15px',
lineHeight:'15px'
}
}, [
h('span',{
style:{
fontSize:'12px',
color:'#666',
display: 'inline-block',
width: '144px',
height:'15px',
marginLeft:'7px',
marginRight:'20px',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap'
},domProps: {
title: params.row.name
}
}, params.row.name),
])
},
renderHeader:(h,params)=>{
var self = this
return h('div', [
h('span', ''),
])
},
},
{
key: 'hxAllNums',
width: 110,
className: 'test-name',
render:(h,params) => {
var self = this
if(params.row.grade==1){
return h('div', [
h('span',
{
style:{
fontSize: '12px',
color:'#666'
}
},
params.row.saleNums),
h('span',{
style:{
width:'40px',
height:'18px',
textAlign:'center',
lineHeight:'18px',
display:'inline-block',
fontSize: '12px',
color: '#333',
marginLeft:'10px',
backgroundColor:'rgba(27,144,240,0.2)',
borderRadius:'5px'
}
}, '一档'),
])
}else if(params.row.grade==2){
return h('div', [
h('span',
{
style:{
fontSize: '12px',
color:'#666'
}
},
params.row.saleNums),
h('span',{
style:{
width:'40px',
height:'18px',
textAlign:'center',
lineHeight:'18px',
display:'inline-block',
fontSize: '12px',
color: '#333',
marginLeft:'10px',
backgroundColor:'rgba(27,144,240,0.4)',
borderRadius:'5px'
}
}, '二档'),
])
}else if(params.row.grade==3){
return h('div', [
h('span',
{
style:{
fontSize: '12px',
color:'#666'
}
},
params.row.saleNums),
h('span',{
style:{
width:'40px',
height:'18px',
textAlign:'center',
lineHeight:'18px',
display:'inline-block',
fontSize: '12px',
color: '#333',
marginLeft:'10px',
backgroundColor:'rgba(27,144,240,0.6)',
borderRadius:'5px'
}
}, '三档'),
])
}else if(params.row.grade==4){
return h('div', [
h('span',
{
style:{
fontSize: '12px',
color:'#666'
}
},
params.row.saleNums),
h('span',{
style:{
width:'40px',
height:'18px',
textAlign:'center',
lineHeight:'18px',
display:'inline-block',
fontSize: '12px',
color: '#333',
marginLeft:'10px',
backgroundColor:'rgba(27,144,240,0.8)',
borderRadius:'5px'
}
}, '四档'),
])
}else if(params.row.grade==5){
return h('div', [
h('span',
{
style:{
fontSize: '12px',
color:'#666'
}
},
params.row.saleNums),
h('span',{
style:{
width:'40px',
height:'18px',
textAlign:'center',
lineHeight:'18px',
display:'inline-block',
fontSize: '12px',
color: '#333',
marginLeft:'10px',
backgroundColor:'rgba(27,144,240,1)',
borderRadius:'5px'
}
}, '五档'),
])
} else{
return h('div', [
h('span', ''),
])
}
},
renderHeader:(h,params)=>{
var self = this
return h('div', [
h('span', '当前核销量'),
])
},
},
]
if(_this.formInline.isMedicalPay==1){
_this.tabelHeard = isYibao
}else{
noYibao = isYibao.splice(0,1)
_this.tabelHeard = noYibao
}
for(var i=0;i<_this.tableBodyList[0].hxNums1.length;i++){
var t = i;
if(_this.formInline.isMedicalPay==1){
if(_this.tabelHeard.length<9){
_this.tabelHeard.push({
align: 'center',
className: 'test-name',
children: [
{
title: '核销数',
key: 'hxNums1',
align: 'center',
// width: 90,
className: 'test-name',
render:(h,params)=>{
var idx = parseInt(params.column._index/2-1);
var ss = params.row.hxNums1[idx] != undefined ? params.row.hxNums1[idx].writeOffNum : '';
return h('div', [
h('span',{
style:{
fontSize:'12px',
color:'#666'
}
}, ss),
]);
},
},
{
title: '实名数',
key: 'hxNums1',
align: 'center',
// width: 90,
className: 'test-name',
render:(h,params)=>{
var idx = parseInt(params.column._index/2)-1;
var ss = params.row.hxNums1[idx] != undefined ? params.row.hxNums1[idx].realNameNum : '';
return h('div', [
h('span',{
style:{
fontSize:'12px',
color:'#666'
}
}, ss),
]);
}
}
],
renderHeader:(h,params)=>{
var idx = parseInt(params.column._index/2);
var ss = _this.tableBodyList[0].hxNums1[params.index-2].hfTime;
return h('div', [
h('span', ss),
]);
},
});
}
}else{
if(_this.tabelHeard.length<8){
_this.tabelHeard.push({
align: 'center',
className: 'test-name',
children: [
{
title: '核销数',
key: 'hxNums1',
align: 'center',
className: 'test-name',
render:(h,params)=>{
var idx = parseInt(params.column._index/2);
var ss = params.row.hxNums1[idx] != undefined ? params.row.hxNums1[idx].writeOffNum : '';
return h('div', [
h('span',{
style:{
fontSize:'12px',
color:'#666'
}
}, ss),
]);
},
},
{
title: '实名数',
key: 'hxNums1',
align: 'center',
className: 'test-name',
render:(h,params)=>{
var idx = parseInt(params.column._index/2)-1;
var ss = params.row.hxNums1[idx] != undefined ? params.row.hxNums1[idx].realNameNum : '';
return h('div', [
h('span',{
style:{
fontSize:'12px',
color:'#666'
}
}, ss),
]);
}
}
],
renderHeader:(h,params)=>{
var idx = parseInt(params.column._index/2);
var ss = _this.tableBodyList[0].hxNums1[params.index-1].hfTime;
return h('div', [
h('span', ss),
]);
},
});
}
}
}
_this.loading = false
},
getList:function(page,isSearch) {
var _this=this;
if(isSearch){
_this.searchFlag = true
_this.pageIndex = 1
}
_this.loading = true
$.ajax({
type: 'post',
url: '../../../../data/zfbDataList.json',
// url: 'http://192.168.1.51:8082/lxzfb/zfbAreaData?date=2021-01-01&isYb=0',
data: {
endTime: _this.formInline.date,
province:_this.formInline.province,
city:_this.formInline.city,
isYb:_this.formInline.isMedicalPay,
},
dataType:'json',
success: function (data) {
if (data.status === 200) {
_this.detailDataListAll = data.body.addressList1
_this.detailTotal = data.body.totalSize
_this.totalPage = _this.detailTotal/_this.detailPageSize
if (_this.detailTotal < _this.detailPageSize) {
_this.tableBodyList = _this.detailDataListAll;
} else {
_this.tableBodyList = _this.detailDataListAll.slice(0, _this.detailPageSize);
}
// _this.tableBodyList = JSON.stringify(data.body);
// _this.tableBodyList = _this.tableBodyList.replace(/loading/g, "_loading").replace(/dataList/g, "hxNums1").replace(/cityList/g, "children").replace(/showChildren/g, "_showChildren")
// _this.tableBodyList = JSON.parse(_this.tableBodyList);
_this.getPackageData()
if(isSearch){
_this.$Message.success('查询成功!');
}
}else{
_this.$Message.error(data.message);
}
_this.searchFlag = false
_this.loading = false
},
error: function () {
_this.loading = false
_this.searchFlag = false
_this.$Message.error('请求失败,请稍后重试!')
}
});
},
handleLoadData:function (item, callback) {
var _this = this
// var urls=''
// if(item.countyName){
// urls= 'http://192.168.1.51:8082/lxzfb/getAreaData?date=2021-01-01&isYb=0&province=云南省&city=文山壮族苗族自治州&type=2&county=文山市'
// }else{
// urls= 'http://192.168.1.51:8082/lxzfb/getAreaData?date=2021-01-01&isYb=0&province=云南省&type=1&city=文山壮族苗族自治州'
// }
$.ajax({
type: 'post',
url: '../../../../data/zfbDataList.json',
// url: urls,
data: {
province:item.province,
city:item.city,
county:item.county,
Type:!item.county?'1':'2' //1获取区 2获取街道
},
dataType:'json',
success: function (data) {
if (data.status === 200) {
// _this.dateValue22 = JSON.stringify(data.body);
// _this.dateValue22 = _this.dateValue22.replace(/loading/g, "_loading").replace(/dataList/g, "hxNums1").replace(/cityList/g, "children").replace(/showChildren/g, "_showChildren")
// _this.dateValue22 = JSON.parse(_this.dateValue22);
_this.dateValue22=data.body.dateValue;
_this.dateValue22.forEach(function (item) {
if(item.townName){
delete item._showChildren;
delete item._loading;
}
})
callback( _this.dateValue22);
}else{
_this.$Message.error(data.message);
}
_this.searchFlag = false
},
error: function () {
_this.searchFlag = false
_this.$Message.error('请求失败,请稍后重试!')
}
});
},
}
四、后端数据格式返回
- 省市后端数据格式
"addressList1":[
{
"id": "111",
"name": "江西",
"_showChildren":true,
"hxNums1": [
{
"hfTime":"2021-01-02",
"writeOffNum":"1",
"realNameNum":"4"
},
{
"hfTime":"2021-01-03",
"writeOffNum":"2",
"realNameNum":"5"
},
{
"hfTime":"2021-01-14",
"writeOffNum":"3",
"realNameNum":"6"
},
{
"hfTime":"2021-01-15",
"writeOffNum":"33333333",
"realNameNum":"555555"
},
{
"hfTime":"2021-01-06",
"writeOffNum":"2",
"realNameNum":"5"
},
{
"hfTime":"2021-01-17",
"writeOffNum":"3",
"realNameNum":"6"
},
{
"hfTime":"2021-01-18",
"writeOffNum":"33333333",
"realNameNum":"555555"
}
],
"children": [
{
"id": "10100",
"province": "江西省",
"city": "南昌市",
"name": "南昌市",
"type": 1,
"saleNums":"111111",
"grade":"1",
"hxNums1": [
{
"hfTime":"2021-01-02",
"writeOffNum":"1",
"realNameNum":"4"
}
],
"_loading": false,
"children": []
},
{
"id": "10100",
"name": "抚州市",
"province": "江西省",
"grade":"2",
"saleNums":"333333",
"type": 1,
"hxNums1": [
{
"hfTime":"2021-01-02",
"writeOffNum":"1",
"realNameNum":"99999"
},
{
"hfTime":"2021-01-03",
"writeOffNum":"3333",
"realNameNum":"5"
}
],
"_loading": false,
"children": []
}
]
},
{
"id": "222",
"name": "浙江省",
"hxNums1": [
{
"hfTime":"2021-01-02",
"writeOffNum":"1",
"realNameNum":"4"
},
{
"hfTime":"2021-01-03",
"writeOffNum":"2",
"realNameNum":"5"
},
{
"hfTime":"2021-01-14",
"writeOffNum":"3",
"realNameNum":"6"
}
],
"_showChildren":true,
"children": [
{
"id": "10100",
"name": "金华市",
"grade":"3",
"hxNums1": [
{
"hfTime":"2021-01-02",
"writeOffNum":"1",
"realNameNum":"4"
},
{
"hfTime":"2021-01-03",
"writeOffNum":"2",
"realNameNum":"5"
},
{
"hfTime":"2021-01-14",
"writeOffNum":"3",
"realNameNum":"6"
}
],
"saleNums":"666666",
"_loading": false,
"children": []
},
{
"id": "10100",
"name": "温州市",
"grade":"5",
"hxNums1": [
{
"hfTime":"2021-01-02",
"writeOffNum":"核销1",
"realNameNum":"实名1"
},
{
"hfTime":"2021-01-03",
"writeOffNum":"核销11",
"realNameNum":"实名22"
},
{
"hfTime":"2021-01-14",
"writeOffNum":"核销111",
"realNameNum":"实名33"
}
],
"saleNums":"333333",
"_loading": false,
"children": []
}
]
},
{
"id": "333",
"name": "福建",
"hxAllNums": "453543",
"_showChildren":true,
"hxNums1": [
{
"hfTime":"2021-01-02",
"writeOffNum":"1111",
"realNameNum":"4"
},
{
"hfTime":"2021-01-03",
"writeOffNum":"2",
"realNameNum":"5555"
},
{
"hfTime":"2021-01-14",
"writeOffNum":"3",
"realNameNum":"6666"
}
],
"children": [
{
"id": "10100",
"name": "南昌市11",
"saleNums":"444444",
"grade":"4",
"type": 1,
"hxNums1": [
{
"hfTime":"2021-01-02",
"writeOffNum":"1",
"realNameNum":"4"
}
],
"_loading": false,
"children": []
},
{
"id": "10100",
"name": "抚州市222",
"saleNums":"555555",
"grade":"5",
"hxNums1": [
{
"hfTime":"2021-01-02",
"writeOffNum":"1",
"realNameNum":"99999"
},
{
"hfTime":"2021-01-03",
"writeOffNum":"3333",
"realNameNum":"5"
}
],
"_loading": false,
"children": []
}
]
}
],
- 县及街道后端返回数据格式
"dateValue": [ { "id": "888", "name": "南丰县", "province": "江西省", "city": "抚州市", "county": "南丰县", "type": "2", "hxNums1": [ { "hfTime":"2021-01-02", "writeOffNum":"111", "realNameNum":"433" }, { "hfTime":"2021-01-03", "writeOffNum":"255", "realNameNum":"577" }, { "hfTime":"2021-01-14", "writeOffNum":"399", "realNameNum":"699" } ], "_loading": false, "children": [ ] }, { "id": "999", "name": "宜黄县", "type": "2", "hxNums1": [ { "hfTime":"2021-01-02", "writeOffNum":"111", "realNameNum":"一晃" }, { "hfTime":"2021-01-03", "writeOffNum":"255", "realNameNum":"宜黄11" }, { "hfTime":"2021-01-14", "writeOffNum":"399", "realNameNum":"699" } ], "_loading": false, "children": [ { "id": "10100", "name": "三叉三叉路口三叉三叉路口", "hxNums1": [ { "hfTime":"2021-01-02", "writeOffNum":"1", "realNameNum":"4" } ] }, { "id": "10100", "name": "三叉三叉路口三叉三叉路长山路", "hxNums1": [ { "hfTime":"2021-01-02", "writeOffNum":"1", "realNameNum":"长山路11" }, { "hfTime":"2021-01-03", "writeOffNum":"11", "realNameNum":"5" } ] } ] } ],