一般来说,table的某一列需要有可以对当前行进行操作的多个按钮,不管是编辑查看还是上传下载。这部分的实现很多人都写过,这里的写法是将操作的这个部分抽离出来,单独做一个组件,每次只需要传操作的类型和对应的处理函数就可以。涉及到很多表格的系统,比如后台管理系统,这样的组件就方便很多。
table-operation组件
首先创建这个操作部分的组件,这个组件其实很简单,就是一个<el-button-group>
包裹了一些<el-button>
,这些按钮通过循环父组件传来的operation
数组渲染,operation
是一个只有按钮类型和按钮上显示的文字两个字段的数组。整个组件的代码如下:
<template>
<el-button-group>
<el-button
v-for="(op,index) in operations"
:key="index"
type="primary"
size="mini"
:icon="icons[op.type]"
@click="clickOperation(op)"
>{{op.title}}</el-button>
</el-button-group>
</template>
<script>
export default {
name: 'TableComponent',
props: {
operations: {
type: Array
},
rawData: {
type: Object
}
},
data () {
return {
icons: {
edit: 'el-icon-edit',
view: 'el-icon-view'
}
};
},
methods: {
clickOperation (operation) {
this.$emit('handleOperation',operation,this.rawData);
}
}
};
</script>
icons
可以规定特定类型的按钮要对应哪种图标
使用el-table的组件中
此处这个组件叫它table-page
,只看<el-table>
的部分
<el-table
:data="list"
class="mt-10"
fit
stripe
empty-text="暂无数据"
:highlight-current-row="true"
>
<el-table-column
v-for="(item, index) in table_title"
:key="index"
:prop="item.prop"
:label="item.label"
:width="item.width?item.width:null"
:min-width="item.minwidth?item.minwidth:null"
:sortable="item.sortable?item.sortable:false"
:align="item.columnAlign"
:header-align="item.titleAlign"
>
<template slot-scope="scope">
<template v-if="item.tag">
<slot name="tags" :scope="scope.row"></slot>
</template>
<span v-else>{{scope.row[item.prop]}}</span>
</template>
</el-table-column>
<!-- 如果需要自定义最后一栏则需传入operates对象,并提供模板 -->
<el-table-column v-if="operates.operate"
:label="operates.label"
:width="operates.width"
:align="operates.columnAlign"
:header-align="operates.titleAlign">
<template slot-scope="scope">
<slot name="operates" :scope="scope"></slot>
</template>
</el-table-column>
</el-table>
可以看到在循环完其他的table数据以后,最后一列渲染出来是一个操作列,此处需要接受来自父组件的operates
对象,这是一个和其他属性数组的每一项相似的列,其实完全可以和其他写在一起,用v-if
来判断(就像上面的tag列似的),这里为了特别说明单独抽出来,放置一个插槽以方便我们使用操作组件。
使用以上两个组件的父组件
在这个父组件中,首先看一下上面所说的传给两个子组件的operation
和operates
的定义
const operates = {
operate: true,
label: '操作',
minwidth: '120px',
titleAlign: 'center',
columnAlign: 'center',
};
const operations = [
{
type: 'edit',
title: '编辑'
},
{
type: 'view',
title: '查看'
}
];
怎么用这两个组件呢
<table-page
:list="list"
:table_title="table_title"
:operates="operates"
>
...// 其他的templates
<template v-slot:operates="scope">
<table-operation
:operations="operations"
:rawData="scope.scope.row"
@handleOperation="handleOperation"
></table-operation>
</template>
</table-page>
可以看到给<table-page>
传了一个operates
,给<table-operation>
传了一个operation
和一个处理操作的函数,这里就是填了之前空出来的插槽,放置这个操作的组件。
那么这个处理操作的函数做了些什么事情呢?
methods: {
...,
handleOperation(op,row) {
if (op.type == 'edit') {
// 编辑它
}
else if (op.type == 'view') {
// 看看它
}
},
...
}
在操作组件中,我们也可以看到给这个函数回传了两个参数,分别是操作组件的这一项以及这一行数据。这两个拿到的话应该能解决大多数场景的问题。根据op
的type
来判断触发的是哪一个按钮,然后做出对应的操作就可以,比如弹一个<el-dialog>
出来~