提交
This commit is contained in:
278
src/components/CustomColumnTable/index.vue
Normal file
278
src/components/CustomColumnTable/index.vue
Normal file
@@ -0,0 +1,278 @@
|
||||
<!--
|
||||
组件方法:
|
||||
getlist: 将分页组件合并,所以需要分页查询列表的数据的方法
|
||||
selectRow:选择行时触发 【配合selectable使用】
|
||||
callFunc: 操作按钮点击时触发 【配合tableBtns使用】 会传递按钮的方法名和行数据
|
||||
clickColumn: 点击表格列时触发 【配合clickColumns使用】 传递到父级时,接受两个参数,(column,row)点击的列名,行数据
|
||||
clickRow: 点击表格行时触发 ps: 建议不要与点击表格列方法同时使用
|
||||
changeSort: 表格列排序
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="table-custom">
|
||||
<span class="custom-table-btn" @click="showCustomClick">自定义列表</span>
|
||||
<el-table v-loading="tableLoading" :data="tableList" border stripe max-height="500" @selection-change="handleSelectionChange" @sort-change="changeSort" @row-click="handleRowClick">
|
||||
<el-table-column v-if="selectable" type="selection" width="60" />
|
||||
<el-table-column type="index" :index="(index)=>((queryParams.pageNum - 1)*queryParams.pageSize + index + 1)" label="序号" width="60" />
|
||||
<el-table-column v-for="(item, index) in tableColumns" :key="index" :label="item.label" :width="item.width" :prop="item.prop" :sortable="sortableColumns.includes(item.prop)" :min-width="clickColumns.includes(item.prop)?150:100">
|
||||
<template slot-scope="{row}">
|
||||
<el-button v-if="clickColumns.includes(item.prop)" type="text" size="mini" @click="$emit('clickColumn', item.prop, row)">{{ row[item.prop] }}</el-button>
|
||||
<span v-else>{{ row[item.prop] }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<slot name="appendColumn" />
|
||||
<el-table-column v-if="tableBtns.length > 0" label="操作" fixed="right" :width="getOpearateWidth()">
|
||||
<template slot-scope="{row}">
|
||||
<template v-if="tableBtns">
|
||||
<template v-for="(item, index) in tableBtns.slice(0, 2)">
|
||||
<el-button v-if="btnShow(row, item)" :key="index" type="text" @click.native.stop="call(item.buttonTrigger, row)">{{ item.buttonName }}</el-button>
|
||||
</template>
|
||||
<template v-if="tableBtns.length > 2">
|
||||
<el-dropdown class="ml0" trigger="click">
|
||||
<el-button type="primary" size="mini">
|
||||
更多
|
||||
<i class="el-icon-arrow-down el-icon--right" />
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<template v-for="(btn, idx) in tableBtns.slice(2, tableBtns.length)">
|
||||
<el-dropdown-item v-if="btnShow(row, item)" :key="idx" @click.native.stop="call(btn.buttonTrigger, row)">{{ btn.buttonName }}</el-dropdown-item>
|
||||
</template>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<pagination :page-sizes="[10, 20, 30, 50, 100, 200]" :total="queryParams.total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="_getTableList" />
|
||||
<el-dialog title="自定义字段配置" :visible.sync="columnsetDialogShow" append-to-body class="dialog500" width="60%">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="18">
|
||||
<el-card shadow="never">
|
||||
<div slot="header">
|
||||
<el-checkbox v-model="columnCheckAll" @change="val => dialogSelectColumn = val ? tableAllFields.map(item=>item.prop):[] ">可选显示数据列</el-checkbox>
|
||||
</div>
|
||||
<el-checkbox-group v-model="dialogSelectColumn" style="line-height: 32px">
|
||||
<el-checkbox v-for="item in tableAllFields" :key="item.prop" :label="item.prop">{{ item.label }}</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-card shadow="never">
|
||||
<div slot="header">
|
||||
已选{{ dialogSelectColumn.length }}项
|
||||
<span class="ml0" style="font-size: 8px">(可拖动排序)</span>
|
||||
</div>
|
||||
<draggable :list="dialogSelectColumn" :animation="340" group="column">
|
||||
<div v-for="item in dialogSelectColumn" :key="item" class="hover-pointer">
|
||||
<div style="line-height: 24px;">{{ tableAllFields.find(column=> column.prop === item).label }}</div>
|
||||
</div>
|
||||
</draggable>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<span slot="footer">
|
||||
<el-button @click="columnsetDialogShow = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleChangeColumns">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import draggable from 'vuedraggable'
|
||||
export default {
|
||||
components: { draggable },
|
||||
props: {
|
||||
tableList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
tableLoading: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
queryParams: {
|
||||
required: true,
|
||||
type: Object,
|
||||
default: () => ({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
}),
|
||||
},
|
||||
// 表格操作按钮
|
||||
tableBtns: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
// 表格可选
|
||||
selectable: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
/**
|
||||
* 接口访问得到的所有表格列/或者写死的表格列格
|
||||
* 格式是: { pror: '', label: '' }
|
||||
*/
|
||||
tableAllFields: {
|
||||
required: true,
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
/**
|
||||
* 默认表格列
|
||||
* 字符串数组: prop 对应值(字段名)
|
||||
*/
|
||||
defaultColumns: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
tablename: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
// 可点击的列
|
||||
clickColumns: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
// 控制按钮隐藏
|
||||
btnShowValid: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
// 可排序的列
|
||||
sortableColumns: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
columnsetDialogShow: false,
|
||||
columnCheckAll: false,
|
||||
dialogSelectColumn: [],
|
||||
name: this.tablename || this.$route.name,
|
||||
customColumns: [], // 本地缓存的表格列
|
||||
tableColumns: [], // 实际展示表格列
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
tableAllFields: {
|
||||
handler(val) {
|
||||
const localStr = localStorage.getItem(this.name)
|
||||
const arr = localStr ? localStr.split(',') : []
|
||||
if (this.isNullOrEmpty(arr)) {
|
||||
this.tableColumns = val
|
||||
.filter((item) => this.defaultColumns.includes(item.prop))
|
||||
.sort(
|
||||
(a, b) =>
|
||||
this.defaultColumns.indexOf(a.prop) -
|
||||
this.defaultColumns.indexOf(b.prop)
|
||||
)
|
||||
this.customColumns = this.defaultColumns
|
||||
} else {
|
||||
this.tableColumns = val
|
||||
.filter((item) => arr.includes(item.prop))
|
||||
.sort((a, b) => arr.indexOf(a.prop) - arr.indexOf(b.prop))
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
created() {
|
||||
if (this.isNullOrEmpty(this.customColumns)) {
|
||||
const localStr = localStorage.getItem(this.name)
|
||||
this.customColumns = localStr ? localStr.split(',') : []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showCustomClick() {
|
||||
this.columnsetDialogShow = true
|
||||
this.dialogSelectColumn = [...this.customColumns]
|
||||
},
|
||||
handleChangeColumns() {
|
||||
this.customColumns = this.dialogSelectColumn
|
||||
this.tableColumns = this.tableAllFields
|
||||
.filter((item) => this.customColumns.includes(item.prop))
|
||||
.sort(
|
||||
(a, b) =>
|
||||
this.customColumns.indexOf(a.prop) -
|
||||
this.customColumns.indexOf(b.prop)
|
||||
)
|
||||
localStorage.setItem(this.name, this.customColumns.join(','))
|
||||
this.columnsetDialogShow = false
|
||||
},
|
||||
_getTableList() {
|
||||
this.$emit('update:queryParams', this.queryParams)
|
||||
this.$emit('getlist')
|
||||
},
|
||||
handleSelectionChange(row) {
|
||||
this.selectable && this.$emit('selectRow', row)
|
||||
},
|
||||
changeSort(val) {
|
||||
this.$emit('changeSort', val)
|
||||
},
|
||||
handleRowClick(row) {
|
||||
this.$emit('clickRow', row)
|
||||
},
|
||||
call(funcName, row) {
|
||||
this.$emit('callFunc', funcName, row)
|
||||
},
|
||||
getOpearateWidth() {
|
||||
let width = 30
|
||||
for (let index = 0; index < this.tableBtns.length; index++) {
|
||||
if (index < 2) {
|
||||
const column = this.tableBtns[index]
|
||||
width += column.buttonName.length * 15
|
||||
column.buttonColor !== 'text' && (width += 30)
|
||||
} else {
|
||||
width += 70 // 更多
|
||||
break
|
||||
}
|
||||
}
|
||||
return width
|
||||
},
|
||||
btnShow(row, btn) {
|
||||
if (this.isNullOrEmpty(this.btnShowValid)) {
|
||||
return true
|
||||
} else {
|
||||
let show = true
|
||||
for (let i = 0; i < this.btnShowValid.length; i++) {
|
||||
const valid = this.btnShowValid[i]
|
||||
if (row[valid.key] === valid.value) {
|
||||
show = btn.buttonName !== valid.btnName
|
||||
}
|
||||
}
|
||||
return show
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.table-custom {
|
||||
width: calc(100% - 30px);
|
||||
position: relative;
|
||||
}
|
||||
.custom-table-btn {
|
||||
width: 30px;
|
||||
display: block;
|
||||
position: absolute;
|
||||
right: -31px;
|
||||
top: 0;
|
||||
text-align: center;
|
||||
color: cadetblue;
|
||||
border: 1px solid #e6ebf5;
|
||||
font-size: 14px;
|
||||
padding: 5px;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user