x-php-Admin/src/components/xTableSelect/index.vue
2023-12-26 08:36:13 +08:00

257 lines
7.4 KiB
Vue

<!--
* @Descripttion: 表格选择器组件
-->
<template>
<el-select ref="select" v-model="defaultValue" :size="size" :clearable="clearable" :multiple="multiple" :collapse-tags="collapseTags" :collapse-tags-tooltip="collapseTagsTooltip" :filterable="filterable" :placeholder="placeholder" :disabled="disabled" :filter-method="filterMethod" @remove-tag="removeTag" @visible-change="visibleChange" @clear="clear">
<template #empty>
<div class="x-table-select__table" v-loading="loading">
<div class="x-table-select__header">
<slot name="header" :data="formData" :form="form" :submit="formSubmit"></slot>
</div>
<el-table ref="table" :data="tableData" :height="245" :highlight-current-row="!multiple" @row-click="click" @select="select" @select-all="selectAll">
<el-table-column v-if="multiple" type="selection" width="55"></el-table-column>
<slot></slot>
</el-table>
<div class="x-table-select__page">
<el-pagination small background layout="prev, pager, next" :total="total" :page-size="limit" v-model:currentPage="currentPage" @current-change="reload"></el-pagination>
</div>
</div>
</template>
</el-select>
</template>
<script>
import config from "@/config/tableSelect";
export default {
props: {
modelValue: null,
api: { type: String, default: '' },
params: { type: Object, default: () => { } },
form: { type: Array, default: () => [] },
placeholder: { type: String, default: "请选择" },
size: { type: String, default: "default" },
clearable: { type: Boolean, default: false },
multiple: { type: Boolean, default: false },
filterable: { type: Boolean, default: false },
collapseTags: { type: Boolean, default: false },
collapseTagsTooltip: { type: Boolean, default: false },
disabled: { type: Boolean, default: false },
mode: { type: String, default: "popover" },
props: { type: Object, default: () => { } }
},
data() {
return {
loading: false,
defaultValue: [],
tableData: [],
limit: config.limit,
total: 0,
currentPage: 1,
defaultProps: {
label: config.props.label,
value: config.props.value,
page: config.request.page,
limit: config.request.limit,
field: config.props.field,
},
formData: {},
}
},
computed: {
},
watch: {
modelValue: {
handler() {
this.defaultValue = this.modelValue
this.autoCurrentLabel()
},
deep: true
}
},
mounted() {
this.defaultProps = Object.assign(this.defaultProps, this.props);
this.defaultValue = this.modelValue
if (Object.keys(this.defaultProps.field).length === 0) {
this.defaultProps.field = {
[this.defaultProps.value]: this.defaultProps.value,
[this.defaultProps.label]: this.defaultProps.label,
}
}
this.defaultProps.skey = this.defaultProps.skey || this.defaultProps.value;
this.autoCurrentLabel()
},
methods: {
//表格显示隐藏回调
visibleChange(visible) {
if (visible) {
this.currentPage = 1
this.formData = {}
this.getData()
} else {
this.autoCurrentLabel()
}
},
//获取表格数据
async getData() {
this.loading = true;
var reqData = {
[this.defaultProps.page]: this.currentPage,
[this.defaultProps.limit]: this.limit,
}
Object.assign(reqData, this.params, this.formData)
var res = await this.$http.get(this.api, reqData, { cacheparameters: 1 });
var parseData = config.parseData(res)
this.tableData = parseData.rows;
this.total = parseData.total;
this.loading = false;
//表格默认赋值
this.$nextTick(() => {
if (typeof this.defaultValue === 'undefined') {
this.defaultValue = this.multiple ? [] : {};
}
if (this.multiple) {
this.defaultValue.forEach(row => {
var setrow = this.tableData.filter(item => item[this.defaultProps.value] === row[this.defaultProps.skey])
if (setrow.length > 0) {
this.$refs.table.toggleRowSelection(setrow[0], true);
}
})
} else {
var value = typeof this.defaultValue === 'object' ? this.defaultValue[this.defaultProps.skey] : this.defaultValue;
var setrow = this.tableData.filter(item => item[this.defaultProps.value] === value)
this.$refs.table.setCurrentRow(setrow[0]);
}
this.$refs.table.setScrollTop(0)
})
},
//插糟表单提交
formSubmit() {
this.currentPage = 1
this.getData()
},
//分页刷新表格
reload() {
this.getData()
},
//自动模拟options赋值
autoCurrentLabel() {
this.$nextTick(() => {
if (this.multiple) {
this.$refs.select.selected.forEach(item => {
item.currentLabel = item.value[this.defaultProps.value]
})
return;
}
this.$refs.select.selectedLabel = typeof this.defaultValue === 'object' ? (this.defaultValue[this.defaultProps.label] || this.defaultValue[this.defaultProps.skey]) : this.defaultValue
})
},
//表格勾选事件
select(rows, row) {
var isSelect = rows.length && rows.indexOf(row) !== -1
if (isSelect) {
var data = {};
for (let key in this.defaultProps.field) {
if (Object.prototype.hasOwnProperty.call(row, key)) {
data[this.defaultProps.field[key]] = row[key]
}
}
this.defaultValue.push(data)
} else {
this.defaultValue.splice(
this.defaultValue.findIndex(item => item[this.defaultProps.skey] == row[this.defaultProps.value]),
1
);
}
this.autoCurrentLabel()
this.$emit('update:modelValue', this.defaultValue);
this.$emit('change', this.defaultValue);
},
//表格全选事件
selectAll(rows) {
var isAllSelect = rows.length > 0
if (isAllSelect) {
rows.forEach(row => {
var isHas = this.defaultValue.find(item => item[this.defaultProps.skey] == row[this.defaultProps.value])
if (!isHas) {
this.defaultValue.push(row)
}
})
} else {
this.tableData.forEach(row => {
var isHas = this.defaultValue.find(item => item[this.defaultProps.skey] == row[this.defaultProps.value])
if (isHas) {
this.defaultValue.splice(
this.defaultValue.findIndex(item => item[this.defaultProps.skey] == row[this.defaultProps.value]),
1
)
}
})
}
this.autoCurrentLabel()
this.$emit('update:modelValue', this.defaultValue);
this.$emit('change', this.defaultValue);
},
click(row) {
if (this.multiple) {
//处理多选点击行
} else {
if (typeof this.defaultValue === 'object') {
for (let key in this.defaultProps.field) {
if (Object.prototype.hasOwnProperty.call(row, key)) {
this.defaultValue[this.defaultProps.field[key]] = row[key]
}
}
} else {
this.defaultValue = row[this.defaultProps.value];
}
this.$refs.select.blur()
this.autoCurrentLabel()
this.$emit('update:modelValue', this.defaultValue);
this.$emit('change', this.defaultValue);
}
},
//tags删除后回调
removeTag(tag) {
var row = this.findRowByKey(tag[this.defaultProps.value])
this.$refs.table.toggleRowSelection(row, false);
this.$emit('update:modelValue', this.defaultValue);
},
//清空后的回调
clear() {
this.$emit('update:modelValue', this.defaultValue);
},
// 关键值查询表格数据行
findRowByKey(value) {
return this.tableData.find(item => item[this.defaultProps.value] === value)
},
filterMethod() {
this.getData()
},
// 触发select隐藏
blur() {
this.$refs.select.blur();
},
// 触发select显示
focus() {
this.$refs.select.focus();
}
}
}
</script>
<style scoped>
.x-table-select__table {
padding: 12px;
}
.x-table-select__page {
padding-top: 12px;
}
</style>