封装element ui table, 支持自定义列的展示和按照指定顺序展示
自定义列需要在引用页面重新写一下,这样就可以定义化了,多数用于一些转换,或者操作列场景下,自行考虑即可,我们粉转成一个组件,那么不用每个table页面按照官方的这种el-table-column写法:
比如这种:
<el-table-column label="状态" > <template slot-scope="{row}"> <span class="link-type">{{ row.status }}</span> </template> </el-table-column>
下面我们封装组件,代码如下 :
1.组件页面:
<template>
<div class="table-container">
<el-table
id="iTable"
ref="mutipleTable"
v-loading.iTable="options.loading"
:data="list"
:stripe="options.stripe"
:highlight-current-row="options.highlightCurrentRow"
border
height="600"
@selection-change="handleSelectionChange"
@row-dblclick="handleRowDblclick"
@row-click="handleRowClick"
>
<!--选择框-->
<el-table-column v-if="options.mutiSelect" type="selection" style="width: 55px;" />
<!--end-->
<!--按钮操作组-->
<el-table-column
v-show="typeof operates != 'undefined'"
v-if="typeof operates != 'undefined' && typeof operates.list !='undefined' && operates.list.filter(_x=>_x.show === true).length > 0"
ref="fixedColumn"
label="操作"
align="center"
:width="operates.width"
:fixed="operates.fixed"
>
<template slot-scope="scope">
<div class="operate-group">
<template v-for="(btn, key) in operates.list">
<div v-if="btn.show" :key="btn.id" class="item">
<!-- <span :style="btn.style" size="mini" :class="btn.class" :plain="btn.plain"-->
<!-- @click="btn.method(key,scope.row)">{{ btn.label }}-->
<!-- </span>-->
<el-button
:type="btn.type"
size="mini"
:icon="btn.icon"
:disabled="btn.disabled"
:plain="btn.plain"
@click.native.prevent="btn.method(key,scope.row)"
>{{ btn.label }}
</el-button>
</div>
</template>
</div>
</template>
</el-table-column>
<!--end-->
<!--数据列-->
<template v-for="(column, index) in columns">
<el-table-column
:key="column.label"
:prop="column.prop"
:label="column.label"
:align="column.align"
:width="column.width"
>
<template slot-scope="scope">
<template v-if="!column.render">
<template v-if="column.formatter">
<span v-html="column.formatter(scope.row, column)" />
</template>
<template v-else>
<span>{{ scope.row[column.prop] }}</span>
</template>
</template>
<template v-else>
<expand-dom :column="column" :row="scope.row" :render="column.render" :index="index" />
</template>
</template>
</el-table-column>
</template>
<!--end-->
</el-table>
<div class="pagination-container" v-show="showPage">
<pagination v-show="total>0" :total="total" :page.sync="currentPage" :limit.sync="pageSize" @pagination="handelPageChange" />
</div>
</div>
</template>
<!--end-->
<script>
import Pagination from '@/components/Pagination'
export default {
// 组件
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)
}
},
Pagination
},
props: {
list: {
type: Array,
default: function() {
return []
}
}, // 数据列表
columns: {
type: Array,
// Type of the default value for 'options' prop must be a function.(vue/require-valid-default-prop)
default: function() {
return []
}
}, // 需要展示的列 === prop:列数据对应的属性,label:列名,align:对齐方式,width:列宽
operates: {
type: Object,
default: function() {
return {}
}
}, // 操作按钮组 === label: 文本,type :类型(primary / success / warning / danger / info / text),show:是否显示,icon:按钮图标,plain:是否朴素按钮,disabled:是否禁用,method:回调方法
options: {
type: Object,
default: function() {
return {
loading: false, // 不加载loading
stripe: false, // 是否为斑马纹 table
highlightCurrentRow: false // 是否要高亮当前行
}
}
}, // table 表格的控制参数
/**
* @total 数据总条数
*/
total: {
type: Number,
default: 0
},
showPage: {
type: Boolean,
default: true
}
},
// 数据
data() {
return {
page: 1,
limit: 10,
pageIndex: 1,
multipleSelection: [] // 多行选中
}
},
computed: {
currentPage: {
get() {
return this.page
},
set(val) {
this.$emit('update:page', val)
}
},
pageSize: {
get() {
return this.limit
},
set(val) {
this.$emit('update:limit', val)
}
}
},
mounted() {
},
methods: {
// 多行选中
handleSelectionChange(val) {
this.multipleSelection = val
this.$emit('handleSelectionChange', val)
},
// 显示 表格操作弹窗
showActionTableDialog() {
this.$emit('handelAction')
},
//翻页
handelPageChange(val){
console.log(val)
this.$emit('handelPageChange', val)
},
//单击事件
handleRowDblclick(val) {
this.multipleSelection = val
this.$emit('handleRowDblclick', val)
},
//单击行事件
handleRowClick(val) {
this.multipleSelection = val
this.$emit('handleRowClick', val)
},
}
}
</script>
<style>
.operate-group {
display: flex;
flex-direction: row;
justify-content: space-around;
}
</style>
2.模板页面调用如下:
<template>
<div class="app-container calendar-list-container">
<el-row>
<el-col :span="24">
<div>
<victable
:list="list"
@handleSelectionChange="handleSelectionChange"
@handleRowClick="handleRowClick"
@handleRowDblclick="handleRowDblclick"
:options="options"
:columns="columns"
:operates="operates"
@handelPageChange="getList"
:total="total"
:page.sync="listQuery.page"
:limit.sync="listQuery.limit"
:showPage="isShowPage">
</victable>
</div>
</el-col>
</el-row>
</div>
</template>
<script>
import victable from '@/components/Victable'
import { fetchList } from '@/api/user'
export default {
name: 'table1',
components: {
victable,
},
computed: {},
data() {
return {
list: [], // table数据
listQuery: {
page: 1,
limit: 10,
systemname: undefined,
},
total: 0,
isShowPage: true,
options: {
stripe: true, // 是否为斑马纹 table
loading: true, // 是否添加表格loading加载动画
highlightCurrentRow: true, // 是否支持当前行高亮显示
mutiSelect: true, // 是否支持列表项选中功能
total: null,
}, // table 的参数
{
prop: 'fromapp',
label: '来源',
align: 'center',
width: '200px'
},
{
prop: 'name',
label: '姓名',
align: 'center',
width: '200px'
// formatter: (row, column, cellValue) => {
// console.log(row.isenable)
// console.log(row)
// return `<span style="white-space: nowrap;color: dodgerblue;">${row.metername}</span>`
// }
},
{
prop: 'username',
label: '用户名',
align: 'center',
},
{
prop: 'stations',
label: '岗位',
align: 'center',
},
{
prop: 'status',
label: '状态',
align: 'center',
render: (h, params) => {
return h('span', {
}, params.row.status === 'open' ? '开启' : '关闭')
}
},
{
prop: 'role',
label: '角色',
align: 'center',
},
],
// 按钮
operates: {
width: 150,
list: [
{
id: '1',
label: '编辑',
style: 'cursor:pointer;color: #409eff;',
show: true,
class: 'el-icon-edit',
plain: true,
type:'primary',
method: (scope, row) => {
console.log(scope)
console.log(row)
this.handleEdit(row)
}
},
{
id: '2',
label: '删除',
style: 'cursor:pointer;color: #b3450e;',
class: 'el-icon-delete',
show: true,
type:'info',
disabled: true,
plain: false,
method: (index, row) => {
this.handleDel(row)
}
}
]
}
}
},
created() {
this.getList();
},
methods: {
// 选中行
handleSelectionChange(val) {
console.log('val:', val)
},
// 编辑
handleEdit(index, row) {
console.log(' index:', index)
console.log(' row:', row)
},
// 删除
handleDel(index, row) {
console.log(' index:', index)
console.log(' row:', row)
},
handleRowClick(index, row) {
console.log(index, row)
},
handleRowDblclick(index, row){
console.log(index, row)
},
getList(val) {
// this.listQuery.loading = true
if(val || val != undefined){
this.listQuery.page = val.page
this.listQuery.limit = val.limit
}
fetchList(this.listQuery).then(response => {
this.options.loading = false
this.list = response.data.items
this.total = response.data.total
})
},
handleSizeChange(val) {
console.log(val)
this.listQuery.limit = val;
this.getList()
},
handleCurrentChange(val) {
console.log(val)
this.listQuery.page = val;
this.getList()
},
}
}
</script>
效果如下:
其中isShowPage可以控制翻页是否显示,当然了组件控制按钮是否显示,按钮的事件,样式,单击行,双击行事件,多选事件,还有其他事件也可以往里面封装,这样就可以节省重复写很多el-table-column这种标签