问题背景
封装el-tabletable的时候有时候忘记语法了,然后问ai或者百度又出来一堆不太正确的回答,作此记录。
1.封装好的table组件完整代码(基础版)
<template>
<div>
<el-table
:data="tableData"
:height="height"
style="width: 100%"
header-cell-class-name="my_headercell_class"
cell-class-name="my_cell_class"
>
<el-table-column
v-for="(column, index1) in tableHeaderList"
:prop="column.prop"
:label="column.label"
:type="column.type"
:width="column.width"
:key="index1"
>
<template slot-scope="{row,$index}">
<!-- 在这里使用 scope.row 和 scope.column 来访问行数据和列配置 -->
<div
class="item"
v-if="!column.slot"
>
<!-- {{ column.render ? column.render(row) : row[column.prop] || '--' }} -->
{{ column.render ? column.render(row) : getNestedProperty(row, column.prop)}}
</div>
<slot
:name="column.slot"
:row="row"
:index="$index"
></slot>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import _ from 'lodash'
export default {
props: {
tableData: {
type: Array,
default: () => []
},
tableHeaderList: {
type: Array,
default: () => []
},
height: {
type: String
}
},
methods: {
// 在 methods 中使用 _.get 来替代 getNestedProperty
getNestedProperty(object, path) {
return _.get(object, path, '')
}
}
}
</script>
<style lang="less">
.my_cell_class{
.cell{
overflow: visible !important;
padding-left: 0;
}
}
.my_headercell_class{
.cell{
padding-left: 0;
}
}
</style>
2.使用
只需要传入tableHeaderList和tableData即可
<template>
<div class="home">
<Table :tableData="tableData" :tableHeaderList="tableHeaderList">
<template slot="rank" slot-scope="{index}">
<div class="rank_top_box">
<span class="rank_number">
{{ index + 1 }}
</span>
<div class="top_bg" :class="'top_bg' + index" v-if="index < 3">
<img class="top_img" :src="require(`@/assets/mass/top_${index + 1}.png`)" alt="">
</div>
</div>
</template>
</Table>
</div>
</template>
<script>
// @ is an alias to /src
import Table from '@/components/Table.vue';
import tableData from './tabledata'
export default {
name: 'HomeView',
computed: {
},
data() {
return {
tableHeaderList: [
{
prop: 'rank',
label: '账号调用排行(TOP10)',
slot: 'rank',
},
{
prop: 'name',
label: '账号名称',
},
{
prop: 'apikey_count',
label: '密钥数',
},
{
prop: 'tenant.name',
label: '所属租户',
},
{
prop: 'project_count',
label: '分配项目数',
},
{
prop: 'req_count',
label: '调用次数',
render: (item) => {
return item.req_count.toLocaleString()
}
}
],
tableData: tableData,
}
},
created() {
},
methods: {
},
components: {
Table
}
};
</script>
<style lang="less" scoped>
.home {
.rank_top_box {
width: 100%;
height: 100%;
overflow: visible;
position: relative;
text-align: center;
.rank_number {
text-align: center;
}
.top_bg {
position: absolute;
top: 0;
left: 0;
width: 160px;
height: 48px;
top: -11px;
.top_img {
width: 28px;
height: 40px;
position: absolute;
top: 50%;
left: 0;
margin-top: -20px;
}
}
.top_bg0 {
background: linear-gradient(90deg, rgba(255, 59, 59, 0.35) 0%, rgba(255, 59, 59, 0) 100%);
}
.top_bg1 {
background: linear-gradient(90deg, rgba(255, 140, 59, 0.35) 0%, rgba(255, 183, 59, 0) 100%);
}
.top_bg2 {
background: linear-gradient(90deg, rgba(255, 216, 59, 0.35) 0%, rgba(255, 245, 59, 0) 100%);
}
}
}
</style>
效果
3.核心代码:
<el-table-column
v-for="(column, index1) in tableHeaderList"
:prop="column.prop"
:label="column.label"
:type="column.type"
:width="column.width"
:key="index1"
>
<template slot-scope="{row,$index}">
<!-- 在这里使用 scope.row 和 scope.column 来访问行数据和列配置 -->
<div
class="item"
v-if="!column.slot"
>
<!-- {{ column.render ? column.render(row) : row[column.prop] || '--' }} -->
{{ column.render ? column.render(row) : getNestedProperty(row, column.prop)}}
</div>
<slot
:name="column.slot"
:row="row"
:index="$index"
></slot>
</template>
</el-table-column>
4.核心解析:
1.一定要在el-table-column中去遍历传进来的tableHeaderList,不要在el-table-column外层加一个div来遍历。
2.最重要的重点是,区分slot,如果外面不需要使用slot,则直接展示值,先要去判断有没有render函数(因为数据可能要经过处理才能展示在table上),如果有render函数,则展示render函数的返回值,
3. 如果没有render函数,那么就使用getNestedProperty来解析深层次的对象(比如我要展示租户,需要取得值是tenant对象下面name的属性值,所以用到这个方法来解析)
4.如果不需要slot,则使用作用域插槽来将数据传递回父组件,让父组件中的插槽进行使用
5.结语
这里仅仅只是写了一个最简单的封装,主要是把封装的核心代码分享出来的,其他的需要什么配置可以自己加哈