<template>
|
<div>
|
<!-- 表格 -->
|
<el-table
|
ref="multipleTable"
|
v-loading="tableLoading"
|
:border="border"
|
:data="tableData"
|
:header-cell-style="{ background: '#f8f8f9', color: '#515a6e' }"
|
: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"
|
>
|
<el-table-column align="center" type="selection" width="55" v-if="isSelection" />
|
<el-table-column
|
align="center"
|
label="序号"
|
type="index"
|
width="60"
|
:index="indexMethod"
|
/>
|
|
<el-table-column
|
v-for="(item, index) in column"
|
:key="index"
|
: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
|
:sortable="item.sortable ? true : false"
|
:type="item.type"
|
:width="item.dataType === 'action'? getWidth(item.operation) : 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>
|
<!-- 图片 -->
|
<div v-else-if="item.dataType == 'image'">
|
<img
|
:src="javaApi + '/img/' + item.prop"
|
alt=""
|
style="width: 40px; height: 40px; margin-top: 10px"
|
/>
|
</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'"
|
size="mini"
|
v-show="o.showHide ? o.showHide(scope.row) : true"
|
:disabled="o.disabled ? o.disabled(scope.row) : false"
|
:icon="iconFn(o)"
|
:plain="o.plain"
|
:style="{ color: o.name === '删除' ? '#f56c6c' : o.color }"
|
:type="o.type | typeFn(scope.row)"
|
@click="o.clickFun(scope.row)"
|
:key="key"
|
>
|
{{ o.name }}
|
</el-button>
|
<el-upload
|
action="#"
|
size="mini"
|
: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"
|
:key="key"
|
>
|
<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-if="item.dataType == 'link'"
|
class="cell link"
|
style="width: 100%"
|
@click="goLink(scope.row, item.linkMethod)"
|
>
|
<span v-if="!item.formatData">{{ scope.row[item.prop] }}</span>
|
</div>
|
<!-- 默认纯展示数据 -->
|
<div v-else class="cell" style="width: 100%">
|
<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>
|
</el-table>
|
<pagination
|
v-show="page.total > 0"
|
:total="page.total"
|
:layout="page.layout"
|
:page.sync="page.current"
|
:limit.sync="page.size"
|
@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: {
|
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,
|
current: 0,
|
size: 10,
|
layout: "total, sizes, prev, pager, next, jumper",
|
};
|
},
|
},
|
},
|
|
methods: {
|
getWidth(row) {
|
let count = 0
|
console.log('row---', row)
|
row.forEach(a => {
|
count += a.name.length
|
})
|
return count * 15 + 40 + 'px'
|
},
|
iconFn(row) {
|
if (row.name === "编辑" || row.name === "修改") {
|
return "el-icon-edit";
|
} else if (row.name === "删除") {
|
return "el-icon-delete";
|
} else if (row.name === "查看") {
|
return "el-icon-view";
|
} else {
|
return row.icon;
|
}
|
// if (typeof (val) === 'function') {
|
// return val(row);
|
// } else return val;
|
},
|
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", { page: page, limit: limit });
|
},
|
indexMethod(index) {
|
// return index * 2;
|
return (this.page.current - 1) * this.page.size + index + 1;
|
},
|
// 点击单元格link事件
|
goLink(row, linkMethod) {
|
if (!linkMethod) {
|
return this.$message.warning("请配置lingk事件");
|
}
|
this.$parent[linkMethod](row);
|
},
|
},
|
};
|
</script>
|
|
<style scoped>
|
.el-table >>> .el-table__empty-text {
|
text-align: center;
|
}
|
.cell {
|
white-space: nowrap;
|
overflow: hidden;
|
text-overflow: ellipsis;
|
padding-right: 4px;
|
padding-left: 4px;
|
}
|
>>> .cell {
|
padding: 0 !important;
|
}
|
.link {
|
color: rgb(64, 158, 255);
|
cursor: pointer;
|
}
|
</style>
|