实现功能
- 通过配置表头标题来实现表格渲染,原理,通过循环将表头数据和接口返回表体数据进行映射匹配,可以自定义表头宽度和内容
- 封装一个
tableList.vue
组件
<template>
<div class="abnormalList">
<!-- 表头 -->
<header class="abnormalTitle">
<span v-for="item in listTitle" :key="item.key" :style="{'width': `${item.width}%`}">{{item.name}}</span>
</header>
<!-- 表体数据滚动 -->
<vue-seamless-scroll
class="wrap"
:data="listData"
:class-option="classOption"
>
<template v-if="listData.length>0">
<div class="table-row" @click="handleClick(item)" v-for="(item, index) in listData" :key="Math.random() + index">
<div class="table-column" :style="{'width': `${itemTitle.width}%`}" v-for="itemTitle in listTitle" :key="itemTitle.name">
<!-- v-if="itemTitle['template']" 存在作用域插槽 -->
<template v-if="itemTitle['template']">
<!-- :name="itemTitle['template']" 作用域插槽名称 -->
<!-- :cell="item[itemTitle['key']]" 拿到listData数据列表中 当前项 数据 -->
<slot :name="itemTitle['template']" :cell="item[itemTitle['key']]">
{{item[itemTitle['key']]}}
</slot>
</template>
<!-- 未设置插槽直接展示 -->
<template v-else>
{{item[itemTitle['key']]}}
</template>
</div>
</div>
</template>
</vue-seamless-scroll>
<div v-if="listData.length===0" class="empty-data">
暂无数据
</div>
</div>
</template>
<script>
import VueSeamlessScroll from "vue-seamless-scroll";
export default {
name: 'tableList',
props: {
clickFlag: {
type: Boolean,
default: false
},
listData: {
type: Array,
required: true,
default() {
return []
}
},
listTitle: {
type: Array,
required: true,
default() {
return []
}
},
},
components: {
VueSeamlessScroll
},
data() {
return {
// VueSeamlessScroll配置项
classOption: {
singleHeight: 36,
limitMoveNum: 3,
},
}
},
created () {
},
methods: {
// 当前行点击事件
handleClick(item) {
this.$emit('rowClick', item)
}
}
}
</script>
<style lang="less" scoped>
.empty-data {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.table-row {
padding: 6px;
display: flex;
flex-wrap: nowrap;
border-bottom: 1px solid rgba(110, 148, 187, 0.2);
align-items: center;
&.active {
cursor: pointer;
}
}
.table-column {
display: inline-block;
text-align: center;
}
.wrap {
width: 100%;
height: 80%;
overflow: hidden;
}
.abnormalList {
font-size: 14px;
color: #52c0ff;
height: 100%;
.abnormalTitle {
background: rgba(82, 192, 255, 0.25);
display: flex;
text-align: center;
justify-content: center;
align-items: center;
padding-left: 10px;
padding-right: 10px;
height: 36px;
}
}
</style>
- 数据来源
// fuwu.js
export const fuwu = [{
"evaluatePerson": "万水",
"rateScore":"10分",
"serveVisits": "yyy",
}, {
"evaluatePerson": "徐权",
"rateScore":"5分",
"serveVisits": "海宁",
}, {
"evaluatePerson": "桂发",
"rateScore":"3分",
"serveVisits": "桐乡",
}, {
"evaluatePerson": "盛林",
"rateScore":"20分",
"serveVisits": "金陵",
}]
- 父组件引用
<template>
<table-list @rowClick="handlerowClick" :listData="listData" :listTitle="abnormalTitleList">
<!-- 作用域插槽自定义cell单元格展示样式 -->
<template v-slot:rankTemp="info">
<div>
<!-- 自定义前三名展示图片 -->
<template v-if="imgSrcData[info.cell]">
<img
class="mingci"
:src="imgSrcData[info.cell]"
alt=""
/>
</template>
<template v-else>{{info.cell}}</template>
</div>
</template>
</table-list>
</template>
<script>
import {fuwu} from './fuwu.js'
import tableList from "./tableList";
export default {
name: "right-two.vue",
data() {
return {
// 自定义单元格样式展示
imgSrcData: {
'1': require('@/assets/imgNew/first.png'),
'2': require('@/assets/imgNew/second.png'),
'3': require('@/assets/imgNew/three.png'),
},
listData: [], // 表格数据
// 表头内容
abnormalTitleList: [
{
name: '排名', // 表头
key: 'rank', // 和接口数据返回key名称一致
width: 10, // 百分比
template: 'rankTemp', // 作用域插槽名称
},
{
name: '护理员姓名',
key: 'evaluatePerson',
width: 25, // 百分比
},
{
name: '任职机构',
key: 'serveVisits',
width: 30, // 百分比
},
{
name: '评分',
key: 'expTime',
width: 25, // 百分比
},
{
name: '',
key: 'arrow',
width: 10, // 百分比
},
],
};
},
mounted() {
this.handleResData(fuwu) // mock接口返回数据
},
methods: {
handlerowClick(item) {
// 点击当前行do something
console.log(item, 'ooo');
},
handleResData(data) {
this.listData = data.map((item, index) => {
return {
...item,
rank: index + 1, // 添加排名
arrow: '>', // 添加跳转图标
}
})
},
},
components: {
tableList
},
};
</script>
<style lang="less" scoped>
.mingci {
width: 18px;
height: 18px;
}
</style>