Element UI 表格进行二次封装
Tips: 文章末尾有完整封装代码
一、继承 element 表格属性
需要将element提供的表格属性使用props传入组件中
props: {
// 表头数据 { slot: 'xxx', header: 'xxx' }[]
// slot:自定义列的slot-name;header:自定义表头的slot-name
columns: Array,
// 表格加载动画
loading: Boolean,
// ...其余属性同 ElementUI 表格 Attributes 直接传入即可
}
二、配置 element 表格的表头
- 使用
props
传入的表头数据遍历得到表格的表头。
<el-table-column v-for="item in columns" :key="item.prop" v-bind="item"></el-table-column>
<!-- or -->
<el-table-column
v-for="item in columns" :key="item.prop"
:prop="item.prop"
:label="item.label"
:align="item.align || 'left'"
:header-align="item.headerAlign || 'left'"
:show-overflow-tooltip="item.tooltip || false"
:min-width="item.minWidth"
:width="item.width"
:fixed="item.fixed"
:class-name="item.columnClass"
:label-class-name="item.labelClassName"
/>
<!-- or -->
<el-table-column v-for="item in columns" :key="item.prop" v-bind="item">
<template v-if="item.header" #header="scope">
<slot :name="item.header" v-bind="scope"></slot>
</template>
<template v-if="item.slot" #default="scope">
<slot :name="item.slot" v-bind="scope"></slot>
</template>
</el-table-column>
- 有些列的数据需要自定义内容,例如:操作列、不同样式的数据展示等。
方式一
需要自定义内容的列可以使用 <slot></slot>
传入自定义内容;这里就不能直接在 <el-table-column></el-table-column>
上使用 v-for
来遍历了,需要使用 <template></template>
来进行 v-for
的循环遍历,此时需要注意的是 v-for
需要定义一个 v-bind:key
但是不能直接将 key
赋给 <template ></template >
但是可以将 key 赋给其他组件 例如 <el-table-column :key="index"></el-table-column>
<!-- 方式一 -->
<template v-for="item in columns">
<!-- 操作列/自定义列 -->
<slot v-if="item.slot" :name="item.slot"></slot>
<el-table-column :key="item.prop" v-bind="item"></el-table-column>
<!-- or
<el-table-column
v-else
:key="item.prop"
:prop="item.prop"
:label="item.label"
:align="item.align || 'left'"
:header-align="item.headerAlign || 'left'"
:show-overflow-tooltip="item.tooltip || false"
:min-width="item.minWidth"
:width="item.width"
:fixed="item.fixed"
:class-name="item.columnClass"
:label-class-name="item.labelClassName"
></el-table-column>
-->
</template>
方式二
在父组件中使用时不用再写 <el-table-column></el-table-column>
标签,直接在 table
中写对应的 slot
内容即可
<el-table-column v-for="item in columns" :key="item.prop" v-bind="item">
<!-- 自定义表头的内容 -->
<template v-if="item.header" #header="scope">
<slot :name="item.header" v-bind="scope"></slot>
</template>
<!-- 自定义列的内容 -->
<template v-if="item.slot" #default="scope">
<slot :name="item.slot" v-bind="scope"></slot>
</template>
</el-table-column>
例如 父组件
<p-table ref="package-table" :columns="columns" :data="data">
<template #name="{ row }">
<span>{{ row.name }}</span>
</template>
</p-table>
<script>
export default {
data: () {
return {
data: [
{
name: '张三',
},
],
columns: [
{
props: 'name',
label: '姓名',
width: '120px',
slot: 'name',
},
],
};
},
}
</script>
三、element 表格事件
Table Events
如果需要使用一些表格返回的事件,可以使用this.$emit()
传递给父组件
也可以直接使用v-on="$attrs"
绑定外部传入的事件
例如:@cell-click 当某个单元格被点击时会触发该事件 row, column, cell, event
// @cell-click="cellClick"
methods: {
cellClick(row, column, cell, event) {
this.$emit('cell-click', {row, column, cell, event})
}
}
Table Methods
如果需要使用一些表格的方法,可以在父组件使用this.$refs['父组件中子组件的ref'].$refs['子组件table的ref'].方法名
调用
例如: clearSort() 用于清空排序条件,数据会恢复成未排序的状态
<!-- 父组件 -->
<template>
<p-table ref="package-table" :columns="columns" :data="data">
<template #name="{ row }">
<span>{{ row.name }}</span>
</template>
</p-table>
</template>
<script>
export default {
data: () {
return {
data: [
{
name: '张三',
age: 24,
},
{
name: '李四',
age: 35,
},
],
columns: [
{
props: 'name',
label: '姓名',
width: '120px',
slot: 'name',
},
{
props: 'age',
label: '年龄',
},
],
};
},
methods: {
// 调用表格方法
clearSort() {
this.$refs['package-table'].$refs.tableRef.clearSort()
}
}
}
</script>
<!-- 子组件 -->
<template>
<el-table ref="tableRef" v-loading="loading" v-bind="$attrs" v-on="$attrs"></el-table>
</template>
至此,对 element 表格的二次封装就已经大功告成了!
完整代码
<template>
<!-- @cell-click="cellClick" -->
<el-table
ref="tableRef"
v-loading="loading"
v-bind="$attrs"
v-on="$attrs"
>
<template v-for="item in columns">
<!-- 自定义table-column -->
<slot v-if="item.slot" :name="item.slot"></slot>
<el-table-column :key="item.prop" v-bind="item" />
<!--
<el-table-column
v-else
:key="item.prop"
:prop="item.prop"
:label="item.label"
:align="item.align || 'left'"
:header-align="item.headerAlign || 'left'"
:show-overflow-tooltip="item.tooltip || false"
:min-width="item.minWidth"
:width="item.width"
:fixed="item.fixed"
:class-name="item.columnClass"
:label-class-name="item.labelClassName"
/>
-->
</template>
<!-- 插入至表格最后一行之后的内容-->
<template #append v-if="$slots.append">
<slot name="append" />
</template>
<!-- 空数据时显示的内容 -->
<template #empty v-if="$slots.empty">
<slot name="empty" />
</template>
</el-table>
</template>
<script>
export default {
name: 'package-table',
props: {
// 表头数据 Table-column Attributes
// { slot: 'xxx', header: 'xxx' }[]
// slot:自定义列的slot-name;header:自定义表头的slot-name
columns: Array,
// 表格加载动画
loading: Boolean,
// ...其余属性同 ElementUI 表格 Attributes 直接传入即可
},
// methods: {
// // 点击单元格
// cellClick(row, column, cell, event) {
// this.$emit('cell-click', {row, column, cell, event})
// }
// },
}
</script>
or
<template>
<el-table
ref="tableRef"
v-loading="loading"
v-bind="$attrs"
v-on="$attrs"
>
<el-table-column v-for="item in columns" :key="item.prop" v-bind="item">
<!-- 自定义表头的内容 -->
<template v-if="item.header" #header="scope">
<slot :name="item.header" v-bind="scope"></slot>
</template>
<!-- 自定义列的内容 -->
<template v-if="item.slot" #default="scope">
<slot :name="item.slot" v-bind="scope"></slot>
</template>
</el-table-column>
<!-- 插入至表格最后一行之后的内容-->
<template #append v-if="$slots.append">
<slot name="append" />
</template>
<!-- 空数据时显示的内容 -->
<template #empty v-if="$slots.empty">
<slot name="empty" />
</template>
</el-table>
</template>
<script>
export default {
name: 'package-table',
props: {
// 表头数据 Table-column Attributes
// { slot: 'xxx', header: 'xxx' }[]
// slot:自定义列的slot-name;header:自定义表头的slot-name
columns: Array,
// 表格加载动画
loading: Boolean,
// ...其余属性同 ElementUI 表格 Attributes 直接传入即可
},
}
</script>
Ending…
ding…
ng…
…
.