基于Vue.js框架和Element UI库编写的表格组件模板。它包含了一系列的自定义选项和事件处理,使得表格可以根据不同的需求进行灵活的展示和操作。下面是对代码的详细解释:
模板部分(Template)
el-table
:这是Element UI中的表格组件,用于展示数据。v-loading
:当数据正在加载时,显示加载动画。:data
:绑定表格的数据源。:height
:设置表格的高度。@selection-change
:当选择行发生变化时触发的事件。:row-class-name
:为表格行指定一个类名,可以用来设置行的样式。:header-cell-style
:为表头单元格指定样式。stripe
:是否为斑马纹 table。v-for
:循环渲染列,根据column
数组中的配置来创建el-table-column
组件。
脚本部分(Script)
filters
:定义了一些Vue过滤器,用于对数据进行格式化处理。props
:定义了组件的属性,包括表头样式、是否显示多选框、表格高度、加载状态、选择变化事件处理函数、列配置、行样式函数和表格数据。methods
:定义了一些方法,用于格式化数据类型和数据格式。
样式部分(Style)
scoped
:表示样式的作用域限定在当前组件内。white-space: pre-wrap;
:设置span
标签的空白符处理方式,保持空白符的可见性。.el-table .warning-row
和.el-table .success-row
:定义了表格中警告和成功状态行的背景色。.app-container /deep/
:使用深度选择器来覆盖Element UI组件的默认样式,设置表格和单元格的背景色为透明。
整体来看,这个表格组件非常灵活,可以通过传入不同的column
配置来渲染不同类型的列,如带有选择框、按钮、进度条、标签等。同时,它还支持自定义行样式和表头样式,以及通过事件处理函数来进行交互。
<template>
<el-table
ref="multipleTable"
v-loading="tableLoading"
:data="tableData"
element-loading-text="拼命加载中"
:height="height"
element-loading-spinner="el-icon-loading"
element-loading-background="rgba(20, 60, 133, 0.8)"
tooltip-effect="dark"
style="width: 100%; "
border
:row-class-name="rowClassName"
:header-cell-style="headerStyle"
stripe
@selection-change="handleSelectionChange"
>
<template v-if="isSelection">
<el-table-column type="selection" width="55" />
</template>
<!-- 这里对数据进行处理 key不能加在template上,只能加在el-table-column上-->
<template v-for="(item,index) in column">
<el-table-column
:key="index"
:label="item.label"
:type="item.type"
:width="item.width"
:fixed="item.fixed"
:sortable="item.sortable?true:false"
:filters="item.filters"
:column-key="item.columnKey"
:filtered-value="item.filteredValue"
:filter-multiple="item.filterMultiple"
:min-width="item.minWidth"
align="center"
>
<!-- <div class="123" v-if="item.type == ''"> -->
<template v-if="item.hasOwnProperty('colunmTemplate')" :slot="item.colunmTemplate" slot-scope="scope">
<slot v-if="item.theadSlot" :name="item.theadSlot" :row="scope.row" :index="index" />
</template >
<template slot-scope="scope">
<!-- 插槽 -->
<div v-if="item.dataType == 'slot'">
<slot v-if="item.slot" :name="item.slot" :row="scope.row" :index="scope.$index" />
</div>
<!-- 进度条 -->
<div v-else-if="item.dataType == 'progress'">
<el-progress :percentage="Number(scope.row[item.prop])" />
</div>
<!-- tag -->
<div v-else-if="item.dataType == 'tag'">
<el-tag v-if="typeof dataTypeFn(scope.row[item.prop],item.formatData) == 'string'" :title="scope.row[item.prop] | formatters(item.formatData)" :type="formatType(scope.row[item.prop],item.formatType)">
{{ scope.row[item.prop] | formatters(item.formatData) }}
</el-tag>
<el-tag v-for="(tag,index) in dataTypeFn(scope.row[item.prop],item.formatData)" v-else-if="typeof dataTypeFn(scope.row[item.prop],item.formatData) == 'object'" :key="index" :title="scope.row[item.prop] | formatters(item.formatData)" :type="formatType(tag,item.formatType)">
{{ item.tagGroup ? tag[item.tagGroup.label]?tag[item.tagGroup.label]:tag : tag }}
</el-tag>
<el-tag v-else :title="scope.row[item.prop] | formatters(item.formatData)" :type="formatType(scope.row[item.prop],item.formatType)">
{{ scope.row[item.prop] | formatters(item.formatData) }}
</el-tag>
</div>
<!-- 按钮 -->
<div v-else-if="item.dataType == 'option'">
<el-button
v-for="(o, key) in item.operation"
v-show="o.showHide?o.showHide(scope.row):true"
:key="key"
:icon="o.icon | iconFn(scope.row)"
:disabled="o.disabled?o.disabled(scope.row):false"
:plain="o.plain"
:type="o.type | typeFn(scope.row)"
:size="o.size"
@click="o.clickFun(scope.row,scope.$index)"
>
{{ o.name }}
</el-button>
</div>
<!-- 默认纯展示数据 -->
<div v-else>
<span v-if="!item.formatData">{{ scope.row[item.prop] }}</span>
<span v-else>{{ scope.row[item.prop] | formatters(item.formatData) }}</span>
</div>
</template>
</el-table-column>
</template>
</el-table>
</template>
<script>
export default {
filters:{
iconFn(val, row) {
if (typeof (val) === 'function') {
return val(row)
} else return val
},
typeFn(val, row) {
console.log(val,row,'11111111');
if (typeof (val) === 'function') {
return val(row)
} else return val
},
describeConts(val, describeCont) {
if (typeof (describeCont) === 'function') {
return describeCont(val)
} else return val
},
formatters(val, format) {
if (typeof (format) === 'function') {
return format(val)
} else return val
}
},
props:{
headerStyle:{//默认的头部背景色
type: Object,
default: () => {
return {
background: '#0e3372',
color: '#cccccc'
}
}
},
isSelection: {//是否是多选框
type: Boolean,
default: false
},
height: {
type: Number,
default: null
},
tableLoading: {//是否显示加载动画
type: Boolean,
default: false
},
handleSelectionChange: {
type: Function,
default: () => {
return () => {}
}
},
headerCellStyle: {
type: Object,
default: () => {
return {}
}
},
column: {
type: Array,
default() {
return [
]
}
},
rowClassName: {
type: Function,
default: () => {
}
},
tableData: {
type: Array,
default() {
return []
}
}
},
methods: {
formatType(val, format) {
if (typeof (format) === 'function') {
return format(val)
} else return ''
},
dataTypeFn(val, format) {
if (typeof (format) === 'function') {
return format(val)
} else return val
}
}
}
</script>
<style scoped>
span{
white-space: pre-wrap;
}
.el-table .warning-row {
background: oldlace;
}
.el-table .success-row {
background: #f0f9eb;
}
.app-container /deep/ .el-table, .el-table__expanded-cell {
background-color: transparent;
}
.app-container /deep/ .el-table tr {
background-color: transparent!important;
}
.app-container /deep/ .el-table--enable-row-transition .el-table__body td, .el-table .cell{
background-color: transparent;
}
</style>
要使用这个表格组件,你需要遵循以下步骤:
1. 引入组件
首先,你需要在你的Vue项目中引入这个表格组件。通常,这个组件会被保存在一个单独的文件中,比如CustomTable.vue
。在你的页面组件或者应用入口文件中,导入并注册这个表格组件:
import CustomTable from './CustomTable.vue';
export default {
components: {
CustomTable
},
// ...
};
2. 定义列配置和数据
在你的页面组件的data
函数中,定义column
和tableData
数组,这些数组将用来控制表格的列显示和数据填充。
data() {
return {
column: [
// 定义列的配置,例如:
{
label: '姓名',
prop: 'name',
dataType: 'text', // 数据类型,可以是 'text', 'slot', 'progress', 'tag', 'option' 等
minWidth: 80
},
// ...更多列配置
],
tableData: [
// 表格的数据,例如:
{ name: '张三', age: 25, gender: '男' },
// ...更多数据项
],
// ...其他属性
};
},
3. 在模板中使用组件
在你的页面模板中,插入CustomTable
组件,并绑定必要的属性和事件。
<template>
<div>
<!-- 使用自定义表格组件 -->
<CustomTable
:tableData="tableData"
:column="column"
:isSelection="true" <!-- 如果需要选择框 -->
:height="500" <!-- 表格高度 -->
@selection-change="handleSelectionChange" <!-- 选择变化事件 -->
:headerStyle="{ background: '#f5f5f5', color: '#333' }" <!-- 表头样式 -->
:rowClassName="rowClass" <!-- 行样式 -->
/>
</div>
</template>
4. 处理事件和插槽
如果你的列配置中使用了插槽(slot),你需要在父组件中定义相应的插槽内容。对于事件,如选择框变化事件,你需要在父组件的methods
中定义处理函数。
<template>
<div>
<!-- 插槽示例 -->
<template v-slot:default="slotProps">
<!-- 自定义内容 -->
</template>
<!-- 组件使用 -->
<CustomTable
:tableData="tableData"
:column="column"
// ...
/>
</div>
</template>
methods: {
handleSelectionChange(selection) {
// 处理选择框变化事件
console.log(selection);
},
rowClass({ row, rowIndex }) {
// 根据行数据或索引返回样式
if (rowIndex % 2 === 0) {
return 'warning-row';
} else {
return 'success-row';
}
}
// ...
}
5. 自定义方法和过滤器
如果你需要自定义数据处理方法或过滤器,可以在父组件中定义它们,并在filters
中注册。这些方法和过滤器将在表格组件中被用来格式化数据。
filters: {
customFormatter(value) {
// 自定义格式化逻辑
return value.toString().toUpperCase();
}
},
methods: {
customMethod(row) {
// 自定义方法逻辑
// 可以基于行数据进行操作
}
}
在表格组件的column
配置中,你可以通过dataTypeFn
、formatType
等属性来引用这些自定义的方法和过滤器。
6. 完整示例
下面是一个完整的父组件使用表格组件的示例:
<template>
<div>
<CustomTable
:tableData="tableData"
:column="column"
:isSelection="true"
:height="500"
@selection-change="handleSelectionChange"
:headerStyle="{ background: '#f5f5f5', color: '#333' }"
:rowClassName="rowClass"
/>
</div>
</template>
<script>
import CustomTable from './CustomTable.vue';
export default {
components: {
CustomTable
},
data() {
return {
tableData: [
{ name: '张三', age: 25, gender: '男' },
// ...更多数据项
],
column: [
{
label: '姓名',
prop: 'name',
dataType: 'text',
minWidth: 80
},
{
label: '年龄',
prop: 'age',
dataType: 'progress', // 假设年龄用进度条表示
minWidth: 100
},
// ...更多列配置
],
// ...其他属性
};
},
methods: {
handleSelectionChange(selection) {
console.log(selection);
},
rowClass({ row, rowIndex }) {
if (rowIndex % 2 === 0) {
return 'warning-row';
} else {
return 'success-row';
}
}
},
filters: {
customFormatter(value) {
return value.toString().toUpperCase();
}
}
};
</script>
通过以上步骤,你可以在你的Vue应用中使用这个自定义的表格组件,并根据需要进行灵活的配置和扩展。
在表格配置中添加处理事件的按钮
你需要在column
数组中定义一个具有dataType
为'option'
的对象,这个对象将包含一个operation
数组,用来定义按钮的配置。每个按钮配置对象应包含name
(按钮显示的文本)、icon
(按钮图标)、type
(按钮类型)、size
(按钮大小)、plain
(是否为朴素按钮)、disabled
(是否禁用按钮)以及clickFun
(点击按钮时触发的事件处理函数)。
以下是一个具体的配置示例:
data() {
return {
column: [
// ...其他列配置
{
label: '操作',
dataType: 'option', // 指定该列为操作列,将渲染按钮
minWidth: 120, // 列宽
operation: [
{
name: '编辑', // 按钮显示的文本
icon: 'el-icon-edit', // 按钮图标
type: 'primary', // 按钮类型
size: 'mini', // 按钮大小
clickFun: this.editRow // 点击按钮时触发的事件处理函数
},
{
name: '删除',
icon: 'el-icon-delete',
type: 'danger',
size: 'mini',
plain: true, // 朴素按钮
disabled: false, // 是否禁用按钮
clickFun: this.deleteRow // 点击按钮时触发的事件处理函数
}
]
}
],
tableData: [
// 表格的数据
],
// ...其他数据和方法
};
},
methods: {
editRow(row, index) {
// 编辑操作的逻辑
console.log('编辑操作', row, index);
},
deleteRow(row, index) {
// 删除操作的逻辑
console.log('删除操作', row, index);
// 通常这里会有一个确认操作的弹窗,用户确认后才执行删除逻辑
}
// ...其他方法
}
在CustomTable
组件的模板中,你需要确保el-table-column
的dataType
设置为'option'
,并且在该列的模板中渲染按钮。这通常是通过v-for
指令在operation
数组上循环来实现的:
<template slot-scope="scope">
<div v-if="item.dataType === 'option'">
<el-button
v-for="(o, key) in item.operation"
:key="key"
:icon="o.icon"
:type="o.type"
:size="o.size"
:plain="o.plain"
:disabled="o.disabled ? o.disabled(scope.row) : false"
@click="o.clickFun(scope.row, scope.$index)"
>
{{ o.name }}
</el-button>
</div>
<!-- ...其他数据类型的渲染 -->
</template>
请注意,clickFun
属性是一个函数,它接受当前行的数据和行索引作为参数。在父组件中,你需要定义相应的方法来处理按钮点击事件,并确保这些方法能够访问到正确的数据和索引。
通过这种方式,你可以在表格中添加具有事件处理功能的按钮,并根据需要自定义按钮的样式和行为。