使用Element-ui框架也很久了,最近项目中有个应用场景,如下图示:
如上截图,在这个table表格中,有显示类文本,有image图片,有switch开关,还有数据编辑操作列。
话不多说,开撸:
首先,在项目文件夹的components中新建CommonTable.bue文件,先生成一个标准的vue页面模板:
<template>
<div>
</div>
</template>
<script>
export default {
}
</script>
<style lang="scss" scoped>
</style>
下面,我们去把element-ui中复制table组件源码,然后针对这个源码进行2次改造,建议对组件中的自定义列模板复制哦:
<template>
<el-table :data="tableData" style="width: 100%" v-loading="config.loading">
<!-- 这里是对tableLableList列表中的字段进行过滤,处理image字段 -->
<el-table-column
v-for="item in tableLabelList.filter(el => el.prop === 'image')"
:key="item.prop"
show-overflow-tooltip
:label="item.label"
:width="item.width ? item.width : 75"
>
<template slot-scope="scope">
<span style="margin-left: 10px">
<img
:src="scope.row.imageUrl"
alt=""
style="width:100px;height:100px"
/>
</span>
</template>
</el-table-column>
<!-- 这里对常规文本类型进行处理,对过滤出image和switch之后的字段进行循环绑定 -->
<el-table-column
v-for="item in tableLabelList.filter(
ele => ele.prop !== 'image' && ele.prop !== 'status'
)"
:key="item.prop"
:label="item.label"
:width="item.width ? item.width : 180"
>
<template slot-scope="scope">
<span style="margin-left:10px">{{ scope.row[item.prop] }}</span>
</template>
</el-table-column>
<!-- 处理switch开关 -->
<el-table-column
v-for="item in tableLabelList.filter(ele => ele.prop === 'status')"
:key="item.prop"
:label="item.label"
:width="item.width ? item.width : 50"
>
<template slot-scope="scope">
<!-- switch开关:之所以disableed,是不希望在这里进行状态修改,而是通过编辑的方式提交post请求修改 -->
<el-switch disabled v-model="scope.row.status"></el-switch>
</template>
</el-table-column>
</el-table>
<!--数据操作列,可以根据实际情况进行逻辑处理 -->
<el-table-column label="操作">
<template slot-scope="scope">
<el-button size="mini" @click="handleEdit(scope.$index, scope.row)"
>编辑</el-button
>
<el-button
size="mini"
type="danger"
@click="handleDelete(scope.$index, scope.row)"
>删除</el-button
>
</template>
</el-table-column>
</template>
<script>
export default {
// 接收父组件传参
props: {
tableData: Array, // 存放父组件传递过来的表数据
tableLabelList: Array, // 存放父组件传递过来的表字段数据
config:Object // 配置项,比如表格每一页多少条数据,数据的加载状态,v-loading指令
},
methods: {
handleEdit(index, row) {
console.log(index, row);
},
handleDelete(index, row) {
console.log(index, row);
}
}
}
</script>
<style lang="scss" scoped>
</style>
上面是整个table组件的完成代码,为了不至于篇幅太长影响阅读,我把二次封装不同类型的代码分开放在下面:
<el-table-column
v-for="item in tableLabelList.filter(el => el.prop === 'image')"
:key="item.prop"
show-overflow-tooltip
:label="item.label"
:width="item.width ? item.width : 75"
>
<template slot-scope="scope">
<span style="margin-left: 10px">
<img
:src="scope.row.imageUrl"
alt=""
style="width:100px;height:100px"
/>
</span>
</template>
</el-table-column>
<el-table-column
v-for="item in tableLabelList.filter(
ele => ele.prop !== 'image' && ele.prop !== 'status'
)"
:key="item.prop"
:label="item.label"
:width="item.width ? item.width : 180"
>
<template slot-scope="scope">
<span style="margin-left:10px">{{ scope.row[item.prop] }}</span>
</template>
</el-table-column>
<el-table-column
v-for="item in tableLabelList.filter(ele => ele.prop === 'status')"
:key="item.prop"
:label="item.label"
:width="item.width ? item.width : 50"
>
<template slot-scope="scope">
<!-- switch开关:之所以disableed,是不希望在这里进行状态修改,而是通过编辑的方式提交post请求修改 -->
<el-switch disabled v-model="scope.row.status"></el-switch>
</template>
</el-table-column>
注意,我这里的处理逻辑是通过判断tableLabelList表头的prop属性,过滤出tableLabelList中不同的表头,处理不同的类型。
既然上面已经二次封装好了,那么就去使用吧:
例如,我这里在GoodsManager.vue页面中引入CommonTable组件:
<script>
// 引入组件
import CommonTable from "@/components/CommonTable"
export default{
//2、注册组件
components:{
CommonTable, // 实际上是: CommonTable:CommonTable,key和value一致时可以省略
}
}
</script>
使用组件和传参:
<!-- 在需要使用CommonTable表格的地方-->
<common-table
<!-- 传参-->
:tableData="saleList"
:tableLabel="tableLabel"
:config="config"
></common-table>
数据如下,在data下初始化数据:
data(){
return{
config: {
page: 1,
total: 20,
loading: false //加载数据
},
tableLabel: [
{
prop: 'image',
label: '图片',
type: 'image',
width: 200
},
{
prop: 'label',
label: '商品名称',
width: 300
},
{
prop: 'ficti',
label: '虚拟销量'
},
{
prop: 'stock',
label: '库存'
},
{
prop: 'sales',
label: '销量'
},
{
prop: 'status',
label: '状态'
}
],
// tableData
tableData:[
{
type: 1,
label: '德尔玛家用床上除螨仪/吸尘器杀菌净化45min续航一体收纳充电CM2000白色',
image:
'http://demo26.crmeb.net/uploads/attach/2019/05/23/33fb5f29f0f52236a85831c8655b9bde.jpg',
ficti: 20,
price: 299,
classify: '卫浴清洁',
stock: 10000,
sales: 68,
status: true,
unit_name: '件',
keywords: ''
},
{
type: 2,
label: '云麦体脂秤称重女智能精准成人脂肪测量仪家用电子体重秤',
image:
'http://demo26.crmeb.net/uploads/attach/2019/05/23/fb40e23473563d0853bb02bc4baa2ea2.jpg',
ficti: 30,
price: 99,
classify: '日用杂货',
stock: 0,
sales: 90,
status: true,
unit_name: '台',
keywords: ''
},
{
type: 1,
label:
'荣耀20青春版 AMOLED屏幕指纹 4000mAh大电池 20W快充 4800万 手机 6GB+64GB 冰岛幻境',
image:
'http://demo26.crmeb.net/uploads/attach/2020/04/27/b2bf3cf3be8a983c1920da54fb9f8579.jpg',
ficti: 22,
price: 2699,
classify: '数码产品',
stock: 800,
sales: 10,
status: true,
unit_name: '台',
keywords: ''
},
{
type: 2,
label: '【超品预售】TOMFORD汤姆福特唇膏4色TF口红黑管套装礼盒16',
image:
'http://demo26.crmeb.net/uploads/attach/2020/04/24/7092e35b87c2849b5f7c48b3e8175f98.jpg',
ficti: 10,
price: 399,
classify: '彩妆香氛',
stock: 30,
sales: 10,
status: false,
unit_name: '件',
keywords: ''
},
{
type: 1,
label: '极蜂天文望远镜天地两用可连接手机拍照望远镜观星星观月亮观景白色',
image:
'http://demo26.crmeb.net/uploads/attach/2019/05/23/759a8317831bbcf71d199277d2f3a8ce.jpg',
ficti: 10,
price: 399,
classify: '数码产品',
stock: 20,
sales: 10,
status: false,
unit_name: '件',
keywords: ''
},
{
type: 2,
label: '心想智能胶囊咖啡机S1102智能全自动手机APP可调2种模式',
image:
'http://demo26.crmeb.net/uploads/attach/2019/05/23/824200dd43d4eb8e7c185993c82b54ad.jpg',
ficti: 10,
price: 1999,
classify: '数码产品',
stock: 0,
sales: 10,
status: false,
unit_name: '件',
keywords: ''
},
{
type: 1,
label: '莱克吉米手持无线吸尘器除螨除尘组合家用大吸力静音',
image:
'http://demo26.crmeb.net/uploads/attach/2019/05/23/2a21667934bd7e26c7edd02687efdd34.jpg',
ficti: 10,
price: 499,
classify: '卫浴清洁',
stock: 400,
sales: 10,
status: false,
unit_name: '件',
keywords: ''
},
{
type: 1,
label: '火候进口整木砧板乌檀木实木家用厨房菜板防霉切菜板',
image:
'http://demo26.crmeb.net/uploads/attach/2019/05/23/4b77ed78767c49b05d365d01b1d95d99.jpg',
ficti: 10,
price: 499,
classify: '日用杂货',
stock: 50,
sales: 10,
status: false,
unit_name: '件',
keywords: ''
},
{
type: 1,
label: '本来设计挂钟原木时钟创意现代简约实木北欧客厅卧室钟表',
image:
'http://demo26.crmeb.net/uploads/attach/2019/05/23/fd79a0af5d4a3eda1572cae99f6725c5.jpg',
ficti: 10,
price: 499,
classify: '日用杂货',
stock: 30,
sales: 10,
status: false,
unit_name: '件',
keywords: ''
},
{
type: 2,
label: '本来设计挂钟原木时钟创意现代简约实木北欧客厅卧室钟表',
image:
'http://demo26.crmeb.net/uploads/attach/2019/05/23/fd79a0af5d4a3eda1572cae99f6725c5.jpg',
ficti: 10,
price: 1499,
classify: '卫浴清洁',
stock: 30,
sales: 10,
status: false,
unit_name: '件',
keywords: ''
}
]
}
}
通过情况,tableData都是通过调用https接口获取的数据列表。
总的来说,二次封装的大致思路如下: