<template>
|
<div>
|
<!-- 表格 -->
|
<el-table
|
ref="multipleTable"
|
v-loading="tableLoading"
|
:border="border"
|
:data="tableData"
|
:header-cell-style="{ background: '#0e3372', color: '#cccccc' }"
|
:height="height"
|
:highlight-current-row="highlightCurrentRow"
|
:row-class-name="rowClassName"
|
:row-style="rowStyle"
|
:row-key="rowKey"
|
stripe
|
style="width: 100%; "
|
tooltip-effect="dark"
|
@row-click="rowClick"
|
@current-change="currentChange"
|
@selection-change="handleSelectionChange"
|
>
|
<template v-if="isSelection">
|
<el-table-column type="selection" width="55" />
|
</template>
|
<template>
|
<el-table-column align="center" label="序号" type="index" width="60" />
|
</template>
|
|
<template v-for="(item, index) in column">
|
<el-table-column :column-key="item.columnKey" :filter-method="item.filterHandler"
|
:filter-multiple="item.filterMultiple" :filtered-value="item.filteredValue"
|
:filters="item.filters" :fixed="item.fixed" :label="item.label"
|
:min-width="item.minWidth" :prop="item.prop"
|
:show-overflow-tooltip="item.showOverflowTooltip"
|
:sortable="item.sortable ? true : false" :type="item.type" :width="item.width"
|
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" :index="index" :name="item.theadSlot" :row="scope.row" />
|
</template>
|
|
<template slot-scope="scope">
|
<!-- 插槽 -->
|
<div v-if="item.dataType == 'slot'">
|
<slot v-if="item.slot" :index="scope.$index" :name="item.slot" :row="scope.row" />
|
</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 == 'action'">
|
<template v-for="(o, key) in item.operation">
|
<el-button
|
v-if="o.type!='upload'"
|
v-show="o.showHide ? o.showHide(scope.row) : true"
|
:disabled="o.disabled ? o.disabled(scope.row) : false"
|
:icon="o.icon | iconFn(scope.row)"
|
:plain="o.plain" :size="o.size"
|
:style="{ 'color': o.color }"
|
:type="o.type | typeFn(scope.row)"
|
@click="o.clickFun(scope.row)">
|
{{ o.name }}
|
</el-button>
|
<el-upload
|
action="#"
|
:on-change="(file, fileList)=>o.clickFun(scope.row,file, fileList)"
|
:multiple="o.multiple?o.multiple:false"
|
:limit="o.limit?o.limit:1"
|
:disabled="o.disabled ? o.disabled(scope.row) : false"
|
:accept="o.accept?o.accept:'.jpg,.jpeg,.png,.gif,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.zip,.rar'"
|
v-if="o.type=='upload'" style="display: inline-block;width: 50px;"
|
v-show="o.showHide ? o.showHide(scope.row) : true"
|
:auto-upload="false"
|
:on-exceed="onExceed"
|
:show-file-list="false">
|
<el-button :size="o.size?o.size:'small'" type="text" :disabled="o.disabled ? o.disabled(scope.row) : false">{{o.name}}</el-button>
|
</el-upload>
|
</template>
|
</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>
|
<pagination
|
v-show="page.total>0"
|
:total="page.total"
|
:page.sync="page.pageNum"
|
:limit.sync="page.pageSize"
|
@pagination="pagination"
|
/>
|
</div>
|
</template>
|
|
<script>
|
// 注:以下是所有配置项,其中最常使用的就是label、width、prop、dataType、slot
|
// label :列名,就是表头上的标签叫什么些什么,类型 string
|
// width:该列宽度, string
|
// prop: table绑定数据字段 string,这一列要展示哪个tableData里面的字段就写哪个字段
|
// dataType: 内置多个基本的element组件可供直接使用 string
|
// slot 当`dataType`为`slot`时必带参数,参数值为插槽的 `slot` 值 string,具体使用方法请看下面的第4点slot插槽的使用
|
// fixed:列是否固定在左侧或者右侧,true 表示固定在左侧 string, boolean
|
// sortable 对应列是否可以排序 boolean, string
|
// filters 数据过滤的选项,数组格式,数组中的元素需要有 text 和 value 属性。Array
|
// columnKey :column 的 key,如果需要使用 filter-change 事件,则需要此属性标识是哪个 column 的筛选条件
|
// filteredValue 选中的数据过滤项,如果需要自定义表头过滤的渲染方式,可能会需要此属性。
|
// filterMultiple 数据过滤的选项是否多选
|
// minWidth 对应列的最小宽度,与 width 的区别是 width 是固定的,min-width 会把剩余宽度按比例分配给设置了 min-width 的列 string
|
// formatData 对数据进行数据处理,接受一个回调函数 (params?: {prop}) => {}
|
// formatType 当 `dataType`为 `tag`时,对标签颜色设置 (params?: {prop}) => { return 'danger'| 'success'... }`
|
// operation 当 `dataType` 为 `option`时,对按钮的 配置,具体配置项以下图为准object
|
// tagGroup 当 `dataType`为 `tag`时,绑定数据集字段显示名称 object
|
/**
|
* 插槽的使用方法:
|
*/
|
/* <div
|
slot="protocolSlot"
|
slot-scope="scope"
|
>
|
<span>{{ scope.row.protocol }}</span>
|
</div>
|
*/
|
/**
|
* 使用formatData进行数据处理
|
*/
|
// {
|
// type: '',
|
// label: '启用状态',
|
// prop: 'is_active',
|
// formatData: (item) => {
|
// const str = item == true ? '已启用' : '未启用'
|
// return str
|
// }
|
// },
|
/**
|
* operation配置
|
*/
|
// operation配置主要是来用于表格里面的操作那一列,通常就会有很多按钮,有以下参数:
|
// name:按钮名称,string
|
// type:按钮类型,`string` | `danger | success`,以elementUi 参数为准
|
// size:按钮大小,以elementUi 参数为准
|
// icon:按钮上的icon,以elementUi 参数为准
|
// plain:按elementUi 文档为准
|
// clickFun:按钮的回调函数
|
export default {
|
name: 'ZTTable',
|
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: {
|
isSelection: {
|
type: Boolean,
|
default: false
|
},
|
height: {
|
type: String,
|
default: null
|
},
|
tableLoading: {
|
type: Boolean,
|
default: false
|
},
|
handleSelectionChange: {
|
type: Function,
|
default: () => {
|
return () => {
|
};
|
}
|
},
|
rowClick: {
|
type: Function,
|
default: () => {
|
return () => {
|
};
|
}
|
},
|
currentChange: {
|
type: Function,
|
default: () => {
|
return () => {
|
};
|
}
|
},
|
border: {
|
type: Boolean,
|
default: true
|
},
|
highlightCurrentRow: {
|
type: Boolean,
|
default: false
|
},
|
headerCellStyle: {
|
type: Object,
|
default: () => {
|
return {};
|
}
|
},
|
column: {
|
type: Array,
|
default() {
|
return [];
|
}
|
},
|
rowClassName: {
|
type: Function,
|
default: () => {
|
|
}
|
},
|
rowStyle: {
|
type: Object || Function,
|
default: () => {
|
}
|
},
|
tableData: {
|
type: Array,
|
default() {
|
return [];
|
}
|
},
|
rowKey: {
|
type: String,
|
default: undefined
|
},
|
page:{
|
type:object,
|
default() {
|
return {
|
total:0,
|
pageNum:0,
|
pageSize:10
|
};
|
}
|
}
|
},
|
|
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;
|
},
|
setCurrent(row) {
|
this.$refs.multipleTable.setCurrentRow();
|
},
|
onExceed(){
|
this.$message.warning('超出文件个数');
|
},
|
pagination(page,limit){
|
this.$emit('pagination',{pageNum: page, pageSize: limit});
|
}
|
}
|
};
|
</script>
|
|
<style scoped>
|
.el-table >>> .el-table__empty-text {
|
text-align: center
|
}
|
</style>
|
|