vue 组件之element-ui table封装
做了这么久的后台管理系统,主要技术栈是vue,因此今天就分享一个二次封装element-ui的table(表格)组件,废话不多说了请看代码。。。。该组件的封装使用render方法进行渲染。。。<template><div class="table-management"><el-tableborderstyle="width: 100%":data="tblData"
·
做了这么久的后台管理系统,主要技术栈是vue,因此今天就分享一个二次封装element-ui的table(表格)组件,废话不多说了请看代码。。。。
该组件的封装使用render方法进行渲染。。。
<template>
<div class="table-management">
<el-table
border
style="width: 100%"
:data="tblData"
v-loading="tbLoading"
element-loading-text="正在加载"
@selection-change="handleSelectionChange"
>
<el-table-column v-if="isSelect" type="selection" width="40">
</el-table-column>
<el-table-column
v-for="(item, index) in column"
:key="index"
:type="item.type"
:index="item.index"
:column-key="item.columnKey"
:label="item.label"
:prop="item.prop"
:width="item.width"
:min-width="item.minWidth"
:fixed="item.fixed"
:header-align="item.headerAlign"
:align="item.align"
:show-overflow-tooltip="showOverflowTooltip"
>
<template slot-scope="scope" slot="header">
//表头显示icon可单独修改,我是默认添加的?icon,并展示相应的tips
<div v-if="item.tip">
<span>{{item.label}}</span>
<el-tooltip placement="right">
<div slot="content">
<div v-for="(items,index) in item.tipData" :key="index">
<p >
{{items.msg}}
</p>
</div>
</div>
<i class="el-icon-question"></i>
</el-tooltip>
</div>
<p v-else>{{item.label}}</p>
</template>
<template slot-scope="scope">
<expand-dom
v-if="item.render"
:render="item.render"
:row="scope.row"
:index="scope.$index"
:column="item"
></expand-dom>
<span v-else>{{ scope.row[item.prop]||'-' }}</span>
</template>
</el-table-column>
</el-table>
//分页封装
<div class="pagination">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page.sync="curPage"
:page-sizes="[10, 20, 30, 40]"
:page-size="pageSize"
:hide-on-single-page="total > 10 ? false : true"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
>
</el-pagination>
</div>
</div>
</template>
<script>
export default {
props: {
tblData: { type: Array },//表格数据list
column: { type: Array },//表格展示的表头以及单元格字段
isSelect: { type: Boolean, default: false },//是否显示选中组件
total: { type: Number },//分页总条数
currentPage:{type:Number,default:1},//分页--当前页
tbLoading:{type:Boolean,default:false},//表格加载loading
pageSize:{type:Number,default:10},//分页--每页显示条数,pageSizes已写死,如有变更可修改
},
components: {
expandDom: {
functional: true,
props: {
row: Object,
render: Function,
index: Number,
column: {
type: Object,
default: null,
},
},
render: (h, ctx) => {
const params = {
row: ctx.props.row,
index: ctx.props.index,
};
if (ctx.props.column) params.column = ctx.props.column;
return ctx.props.render(h, params);
},
},
},
data() {
return {
showOverflowTooltip: true,
};
},
computed: {
curPage:{
get(){
return this.currentPage
},
set(val){
console.log(val);
// this.$emit("handleCurrentChange", val);
}
}
},
methods: {
//选中方法回调
handleSelectionChange(val) {
// 选中事件
this.$emit("handleSelectBtn", val);
},
handleButton(methods, row, index) {
// 按钮事件
this.$emit("handleButton", { methods: methods, row: row, index: index });
},
//分页api(展示每页显示条数)
handleSizeChange(val) {
this.$emit("handleSizeChange", val);
},
//分页点击api(获取当前页数据)
handleCurrentChange(val) {
this.curPage = val;
this.$emit("handleCurrentChange", val);
},
},
mounted() {},
};
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.table-management {
.pagination {
float: right;
margin: 20px;
}
.imgBox {
width: 50px;
height: 50px;
margin: 0 auto;
img {
width: 100%;
height: 100%;
}
}
}
</style>
下面是组件内部调用方法,以及使用心得:
//详细参数可查看组件封装(上一代码块)
//isSelect:是否显示选中组件
//handleSelectBtn:选中方法回调
//handleSizeChange:分页api(展示每页显示条数)
//handleSizeChange:分页点击api(获取当前页数据)
<template>
<div>
<table-tem
@handleSizeChange="handleSizeChange"
@handleCurrentChange="handleCurrentChange"
:tblData="tblData"
:column="column"
:isSelect="true"
:total="total"
@handleSelectBtn="handleSelectBtn"
:currentPage="listQuery.page"
:pageSize="listQuery.pageSize">
</table-tem>
</div>
</template>
<script>
//引入组件table
import tableTem from "@/components/tableTem";
//下面要格式化日期,所以引入moment插件,大佬可自己封装jsApi
import moment from 'moment'
data(){
return{
tblData:[],//表格展示数据list,由接口获取
selectList:[],//储存列表选中的数据
total:0,//total:数据总条数,由接口返回
listQuery:{//接口请求参数
page:1,//表格显示当前页数
pageSize:10//表格显示每页条数
},
column:[//表格展示列,也就是表头字段
{
prop: 'imgUrl',//表格渲染字段
label: 'logo',//表头显示名字
headerAlign: 'center',//表头样式-居中显示
align: 'center',//单元格样式-居中显示
minWidth:'110',//表头+单元格显示最小宽度
render: this.renderImg//当前渲染字段api--列出显示img的api
},
{
prop: 'timeList',
label: '时间段',
headerAlign: 'center',
align: 'center',
render: this.renderTimeList
},
{
prop: 'type',
label: '类型',
headerAlign: 'center',
align: 'center',
render: this.renderType
},
{
prop: 'StatusDesc',
label: '状态',
headerAlign: 'center',
align: 'center',
tip: true,//是否展示表头状态描述提示信息
tipData: [//展示的提示信息数组
{msg: '我是展示在状态表头里面的提示信息1'},
{msg: '我是展示在状态表头里面的提示信息2'}
],
minWidth: 150
},
{
prop: 'createTime',
label: '创建时间',
headerAlign: 'center',
align: 'center',
minWidth:'90',
render:this.renderCreateTime//当前渲染字段api--(后端返回的是时间戳需要前端处理一下)
},
//接下来就着重说一下表格的操作按钮(相同的字段前面都表述清楚了)
{
prop: 'operation',
label: '操作',
headerAlign: 'center',
align: 'center',
minWidth:'110',
render: this.renderOperation//该方法是针对操作一列的按钮的api
}
],
}
},
methods:{
//分页点击
handleCurrentChange(val){
this.listQuery.page=val
//掉接口:获取表格数据接口
},
//获取每页显示条数
handleSizeChange(val){
this.listQuery.pageSize=val
//掉接口:获取表格数据接口
},
// 列表选中回调api
handleSelectBtn(val) {
this.selectList=val;
},
//表格-单元格img渲染api
renderImg(h, { row }){
//row.imgUrl:imgUrl字段由数据返回
if(row.imgUrl){
return h(
"img",
{attrs: {//设置img的属性以及样式
src: row.logoUrl,
width:80,
height:80
}}
);
}else{
return h(
"div",
{attrs: {
width:80,
height:80
}}
);
}
},
//渲染时间数组
renderTimeList (h, {row: {timeList}}) {
let timeListArr = []
for (let i of timeList) {
timeListArr.push(i.startTime + '~' + i.endTime)
}
return h('div', timeListArr.map(function (item, index) {
return h('div', {
}, item)
})
)
},
// 状态渲染类
renderType(h, { row }){
let statusStr=''
if(row.type == 1){
statusStr='类型1'
}else if(row.type== 2){
statusStr='类型2'
}else if(row.type== 3){
statusStr='类型3'
}else{
statusStr=''
}
return h(
"div",
{},
statusStr
);
}
// 时间渲染api,由于列表字段比较多,所以日期+时间换行显示
renderCreateTime(h, { row}) {
if(!row.createTime){
return ''
}
let t=moment(row.createTime).format('YYYY-MM-DD HH:mm:ss')
let tArr=t.split(' ')
//render方法返回的必须是一个数组包裹,下面展示的dom是:由一个div包裹的两个p标签
return h(
"div",
{},[h("p",{style: {margin: 0}},tArr[0]),h("p",{style: {margin: 0}},tArr[1])]
);
},
//下面是操作按钮一列
// 操作
renderOperation (h, {row}) {
return h('div', {
}, [
//有几个按钮就在数组内部以数组元素的方式写入
h('el-button', {//指定按钮样式
props: {//element 按钮类型
type: 'danger',
icon: 'el-icon-edit'//指定按钮上的icon
},
style:{//按钮样式
margin: '0px 0px 5px',
padding:'8px',
cursor: 'pointer',
display:'block'
},
on: {//按钮回调方法
click: () => {
//此处写按钮回调方法
}
}
}, '按钮名字1'),//按钮名字
h('el-button', {
props: {
type: 'primary'
},
style:{
margin: '0px 0px 5px',
padding:'8px',
cursor: 'pointer',
display:'block'
},
on: {
click: () => {
//同上
}
}
},'按钮名字2'),
h('el-button', {
props: {
type: 'success'
},
style:{
margin: '0px',
padding:'8px',
cursor: 'pointer',
display:'block'
},
on: {
click: () => {
//同上
}
}
}, '按钮名字3'),
])
},
}
</script>
基本用法综上所述,由于时间观念就不做赘述了。。。
如有技术上的bug,欢迎各位技术大佬批评指正。。。
更多推荐
已为社区贡献11条内容
所有评论(0)