<!--
* @description 表格组件
* @fileName TableList.vue
* @author Q
* @date 2021/05/15 15:13:45
-->
<template>
<div class="table-container">
<el-table v-if="showTable" ref="filterTable" :data="data" :show-summary="showSummary.show?showSummary.show:null" :summary-method="showSummary.show?summaryMethod:null" :sum-text="showSummary.sumText?showSummary.sumText:null" @filter-change="handleFilterChange" :border="border" :stripe="stripe" empty-text="暂无数据"
style="width: 100%" :show-header="showHeader" :tooltip-effect="tooltipTheme" @selection-change="handleSelectionChange">
<!-- 选择框列 -->
<el-table-column v-if="selection" type="selection" :align="'center'"></el-table-column>
<!-- 排序列 -->
<el-table-column v-if="indexShow" width="100" label="序号" :align="'center'">
<template slot-scope="scope">
<div>
<span>{{ scope.$index + 1 }}</span>
</div>
</template>
</el-table-column>
<template v-for="(item, index) in columns">
<!-- 特殊列处理 -->
<template v-if="item.render">
<!-- visible 是否显示该列 -->
<el-table-column v-if="item.visible" :filters="item.filters?item.filters:null" :column-key="item.prop" :key="index" :prop="item.prop ? item.prop : null" :align="item.align ? item.align : null" :fixed="item.fixed ? item.fixed : null" :label="item.label ? item.label : null"
:show-overflow-tooltip="item.tooltip" :class-name="className" :sortable="item.sortable ? item.sortable : false" :width="item.width ? item.width : null">
<!-- 多级表头 -->
<template v-if="item.children&&item.children.length>0">
<div v-for="(item1, index1) in item.children" :key="index1">
<el-table-column :key="index1" :filters="item.filters?item.filters:null" :column-key="item.prop" :prop="item1.prop ? item1.prop : null" :align="item1.align ? item1.align : null" :fixed="item1.fixed ? item1.fixed : null" :label="item1.label ? item1.label : null"
:show-overflow-tooltip="item1.tooltip" :class-name="className" :sortable="item1.sortable ? item1.sortable : false" :width="item1.width ? item1.width : null">
<exSlot :render="item1.render" :row="scope.row" :index1="scope.$index" :column="item1" />
</el-table-column>
</div>
</template>
<!-- 不是多级表头 -->
<template slot-scope="scope">
<exSlot :render="item.render" :row="scope.row" :index="scope.$index" :column="item" />
</template>
</el-table-column>
</template>
<!-- 正常列 -->
<template v-else>
<!-- visible 是否显示该列 -->
<el-table-column v-if="item.visible" :key="index" :column-key="item.prop" :filters="item.filters?item.filters:null" :prop="item.prop ? item.prop : null" :align="item.align ? item.align : null" :fixed="item.fixed ? item.fixed : null" :label="item.label ? item.label : null"
:class-name="className" :show-overflow-tooltip="item.tooltip" :sortable="item.sortable ? item.sortable : false" :width="item.width ? item.width : null">
<!-- 多级表头 -->
<template v-if="item.children&&item.children.length>0">
<template v-for="(item1, index1) in item.children">
<el-table-column :prop="item1.prop ? item1.prop : null" :column-key="item.prop" :filters="item.filters?item.filters:null" :align="item1.align ? item1.align : null" :fixed="item1.fixed ? item1.fixed : null" :label="item1.label ? item1.label : null"
:show-overflow-tooltip="item1.tooltip" :class-name="className" :sortable="item1.sortable ? item1.sortable : false" :width="item1.width ? item1.width : null">
<template slot-scope="scope">
<span v-html="formatter(scope.row[item1.prop])"></span>
</template>
</el-table-column>
</template>
</template>
<template slot-scope="scope">
<!-- 字典处理 -->
<template v-if="item.dict">
<!-- 判断原始数据是否有效,有效转为字典数据,无效则转为--占位符 -->
<span v-if="!scope.row[item.prop]" v-html="formatter(scope.row[item.prop])"></span>
<dict-tag v-else :options="dict.type[item.prop]" :value="scope.row[item.prop]" />
</template>
<!-- 时间格式化 -->
<span v-else-if="item.time">{{ parseTime(scope.row[item.prop],'{y}-{m}-{d}') }}</span>
<!-- 不做处理 -->
<span v-else v-html="formatter(scope.row[item.prop])"></span>
</template>
</el-table-column>
</template>
</template>
<!-- 操作列 -->
<el-table-column v-if="isEdit === true" label="操作" :align="'center'" width="200" :fixed="fixed">
<template slot-scope="scope">
<slot name="editSlot">
<template>
<el-button type="primary" @click="editClick(scope.row)">编辑</el-button>
<el-button type="danger" @click="deleteClick(scope.row)">删除</el-button>
</template>
</slot>
</template>
</el-table-column>
</el-table>
<el-pagination :style="{float:`${paginationPosition}`}" v-if="pagination" :background="background" :current-page.sync="currentPage" :page-size.sync="currentSize" :layout="layout" :page-sizes="pageSizes" :total="total" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
</div>
</template>
<script>
// 自定义内容的组件
var exSlot = {
functional: true,
props: {
row: Object,
render: Function,
index: Number,
column: {
type: Object,
default: null
}
},
// render 函数
render: (h, context) => {
const params = {
row: context.props.row,
index: context.props.index
}
if (context.props.columns) params.columns = context.props.columns
return context.props.render(h, params)
}
}
export default {
name: 'TableList',
components: { exSlot },
props: {
data: {
type: Array,
default: () => []
},
update: {
type: Number,
default: () => null
},
// 是否显示合计列
showSummary: {
type: Object,
default: () => {
return {
show: false,
sumText: '总计'
}
}
},
tooltipTheme: {
type: String,
default: 'dark'
},
// 是否显示表头
showHeader: {
type: Boolean,
default: true
}
,
// 是否添加排序列
indexShow: {
type: Boolean,
default: true
},
showTable: {
type: Boolean,
default: true
},
// 是否显示选择框列
selection: {
type: Boolean,
default: false,
},
// 字段名
columns: {
type: Array,
default: () => []
},
// 是否含有边框
border: {
type: Boolean,
default: false
},
// 是否显示斑马条纹
stripe: {
type: Boolean,
default: false
},
// 是否是可以编辑的表格
isEdit: {
type: Boolean,
default: false
},
// 是否固定右侧一列,只对右侧操作栏起作用
fixed: {
type: String,
default: 'right'
},
// 是否显示分页
pagination: {
type: Boolean,
default: false
},
// 分页的位置
paginationPosition: {
type: String,
default: 'center'
},
total: {
required: false,
type: Number
},
page: {
type: Number,
default: 1 // 默认第一页
},
limit: {
type: Number,
default: 10 // 默认每页20条
},
pageSizes: {
type: Array,
// default: [10, 20, 30, 50]
default: function () {
return [1, 2, 3, 5] // 默认显示可选的每页多少条数据
}
},
layout: {
type: String,
default: 'total, sizes, prev, pager, next, jumper'
},
background: {
type: Boolean,
default: true
},
autoScroll: {
type: Boolean,
default: true
},
hidden: {
type: Boolean,
default: false
},
className: {
type: String,
default: ''
},
render: {
type: Function,
default: function () { }
}
},
data() {
return {
cloneColumns: []
}
},
computed: {
// 当前页多少条数据并且赋值给父组件
currentPage: {
get() {
return this.page
},
set(val) {
this.$emit('update:page', val)
}
},
// 改变当前页几条数据得值赋值给父组件
currentSize: {
get() {
return this.limit
},
set(val) {
this.$emit('update:limit', val)
}
}
},
created() {
this.cloneColumns = JSON.parse(JSON.stringify(this.columns))
},
watch: {
columns(value) {
}
},
mounted() { },
methods: {
// 自定义合计行
summaryMethod(params) {
const { columns, data } = params
const sums = []
columns.forEach((column, index) => {
if (index === 0) {
sums[index] = '总计'
return
}
const values = data.map(item => item[column.property]);
let num = 0
for (let i = 0; i < values.length; i++) {
if (values[i]) {
num += Number(values[i])
sums[index] = num
} else {
if (isNaN(values[i])) {
} else {
num += Number(values[i])
sums[index] = num
}
}
}
if (column.property === 'lv1Time' || column.property === 'lv2Time') {
if (values.filter(Boolean).length === 0) {
sums[index] = ''
} else {
let num = 0
for (let i = 0; i < values.length; i++) {
if (values[i]) {
num += Number(values[i])
sums[index] = num
} else {
if (isNaN(values[i])) {
} else {
num += Number(values[i])
sums[index] = num
}
}
}
}
}
})
let arr = []
sums.map((i, index) => {
if (index === 0) {
arr.push(i)
} else {
if (!isNaN(i)) {
arr.push(i)
} else {
arr.push('')
}
}
})
return arr
},
handleFilterChange(filters) {
if (filters.length > 0) {
this.$refs.filterTable.clearSelection();
this.$refs.filterTable.toggleRowSelection(filters.pop());
} else {
this.columns.map((item) => {
// 判断当前是那一列进行了筛选
if (item.prop === Object.keys(filters)[0]) {
item.filterValues = filters
}
})
this.$emit('filtersParams', this.columns)
}
},
// 当前行当前列数据是否有效,无效的话,返回--占位符
formatter(row) {
if(row){
return isNaN(parseFloat(row)) && isFinite(row) ? '<span class="isNaN">--</span>' : row
}else{
return '<span class="isNaN">--</span>'
}
},
/**
* @param {*}
* @return {*}
* @author: 刘恋
* @Date: 2021-09-01 11:56:37
* @description: 已选的数据项
*/
handleSelectionChange(val) {
this.$emit('selectVal', val)
},
handleSizeChange(val) {
this.pageSize = val
this.$emit('pagination', { pageIndex: this.page, pageSize: val })
},
handleCurrentChange(val) {
this.$emit('pagination', { pageIndex: val, pageSize: this.limit })
},
// 修改按钮的点击事件
editClick(val) {
this.$emit('edit', val)
},
// 删除按钮点击事件
deleteClick(val) {
this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$emit('del', val)
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
})
})
}
}
}
</script>
<style lang="scss">
.table-container {
text-align: center;
.el-pagination {
margin-left: 0 !important;
margin-top: 0 !important;
background: #fff !important;
height: 112px;
line-height: 112px;
display: flex;
justify-content: center;
align-items: center;
ul {
display: flex;
justify-content: space-around;
align-items: center;
li {
border-radius: 6px !important;
color: #666666 !important;
}
.active {
color: #fff !important;
background: #1677ffff !important;
}
}
button {
border-radius: 6px !important;
color: #666666 !important;
}
}
}
.table-container.el-table {
margin-top: 20px;
}
.table-container .el-pagination {
margin-top: 20px;
margin-left: 20px;
}
.isNaN {
color: red;
}
</style>
table组件
最新推荐文章于 2024-11-02 19:19:35 发布