想要基于element-ui
的table
封装一个表格组件,因为后台管理很多菜单的首页几乎一个样,我想在调用的时候传递tabColumns
、tableData
等关键属性即可:
封装表格my-table.vue
如下:
<template>
<div>
<div class="btns-area">
<el-button-group>
<slot name="btnsArea"></slot>
<el-dropdown :hide-on-click='false'>
<el-button type="default">
显示隐藏列 <span v-show="hiddenColumnTotal > 0">({{ hiddenColumnTotal }})</span><i class="el-icon-arrow-down el-icon--right"></i>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item v-for="head in headers" :key="head.key">
<el-switch v-model="head.isShow" :active-text="head.label"></el-switch><span></span>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-button-group>
</div>
<el-table
ref="myTable"
:data="tabDatas"
highlight-current-row
@row-click='handleRowClick'
@selection-change='handleSelectionChange'
>
<el-table-column type="selection" width="55" v-if="multable"></el-table-column>
<!-- 用户自定义需要显示的列 -->
<el-table-column v-for="c in columns"
:key="c.attr.prop"
v-bind="c.attr"
>
<template slot-scope="scope">
<slot v-if="c.slot" :name="c.attr.prop" :row='scope.row'></slot>
<span v-else>{{ scope.row[c.attr.prop] }}</span>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
name: 'my-table',
props: {
tabColumns: {
type: Array,
required: true,
validator: (cols) => {
return cols.length >= 1 //表格至少需要1列
}
},
tabDatas: Array,
multable: { //是否多选
type: Boolean,
default: true
}
},
computed: {
columns() {
return this.headers.filter(h => h.isShow);
},
hiddenColumnTotal() {
return this.headers.filter(h => !h.isShow).length;
}
},
created() {
this.headers = JSON.parse(JSON.stringify(this.tabColumns));
this.headers = this.headers.map((c) => {
if(c.isShow === undefined){
this.$set(c, 'isShow', true)
}
return c;
});
},
data() {
return {
headers: [],
}
},
methods: {
//单击行
handleRowClick(row) {
this.$refs.myTable.toggleRowSelection(row);
},
handleSelectionChange(selection) {
this.$emit('rowSelectionChanged', selection);
},
}
}
</script>
<style scoped>
.btns-area{
text-align: right;
}
</style>
调用方代码如下(某个列表页):
<template>
<div>
<my-table
:tab-columns='tabColumns'
:tab-datas='tabDatas'
@rowSelectionChanged='rowSelected'
>
<!-- 表格批量操作区域 -->
<template slot="btnsArea">
<el-button type="primary">编辑</el-button>
<el-button type="danger">删除</el-button>
</template>
<!-- 通过slot自定义列:参数,当前行 -->
<template slot='gender' slot-scope="scope">
<el-tag v-if="scope.row.gender == 1" type="success">男</el-tag>
<el-tag v-if="scope.row.gender == 0" type="info">女</el-tag>
</template>
</my-table>
</div>
</template>
<script>
import MyTable from '../../components/my-table'
export default {
name: 'nest-components-demo',
data() {
return {
tabColumns: [
{
attr: {prop: 'userId', label: '用户编号'}
},
{
attr: {prop: 'username', label: '用户名'},
isShow: false
},
{
attr: {prop: 'gender', label: '性别'},
slot: true
},
{
attr: {prop: 'age', label: '年龄', formatter: this.formatterUsername},
},
],
tabDatas: [
{userId: '1', username: 'qingyun', gender: '1', age: 31},
{userId: '2', username: 'aaaaaaaa', gender: '0', age: 21},
{userId: '3', username: 'bbbbbbb', gender: '1', age: 25},
{userId: '4', username: 'cccccccc', gender: '0', age: 27},
],
checkedRows: [],//选中的行
}
},
methods: {
//监听选中的行
rowSelected(rows) {
this.checkedRows = rows;
console.log(this.checkedRows.map(r => r.userId));
},
preview(row) {
console.log(JSON.stringify(row));
},
formatterUsername(row, column) {
console.log('xxxxxxxxxxxxx');
return 'xxx';
}
},
components: {
MyTable,
}
}
</script>
my-table.vue
组件属性说明:
-
tabColumns
需要显示的列。有三个属性(后续会扩展出更多);-
key
: 字段名; -
label
:显示的字符; -
slot=true
:表示该列需要自定义,通过slot-scope
可以得到整行数据;
-
-
tabDatas
表格需要显示的数据;
可以看到,在调用封装好的组件my-table
的时候还是比较简单的,列通过label
和key
显示对应的表头和数据;也可以通过设置列属性slot=true
来自定义要显示的样子。
问题:我希望通过设置tabColumns
列属性的时候,可以新增一个formatter
属性(参考第二段代码中对属性age
的设置),Function
类型,就像 element-ui
默认使用方式一样(参考),用来格式化比较简单的字符串(虽然通过设置slot=true
完全可以做到),
可以使用
:attr
,:listeners
等将你的组件变为高级组件。大概就是这个意思,你再根据你的需求习惯来写。