admin/src/components/piTableSelect/index.vue

255 lines
7.1 KiB
Vue

<template>
<el-select ref="selectRef" 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="pi-table-select__table" :style="{width: tableWidth+'px'}" v-loading="loading">
<div class="pi-table-select__header">
<slot name="header" :form="formData" :submit="formSubmit"></slot>
</div>
<el-table ref="tableRef" :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="45"></el-table-column>
<el-table-column v-else type="index" width="45">
<template #default="scope"><span>{{ scope.$index + (currentPage - 1) * pageSize + 1 }}</span>
</template>
</el-table-column>
<slot></slot>
</el-table>
<div class="pi-table-select__page">
<el-pagination size="small" background layout="prev, pager, next" :total="total" :page-size="pageSize"
v-model:currentPage="currentPage" @current-change="reload"></el-pagination>
</div>
</div>
</template>
</el-select>
</template>
<script setup>
import config from '@/config/select'
import {ref, watch, onMounted, nextTick} from 'vue'
const emit = defineEmits(['update:modelValue', 'change'])
const props = defineProps({
modelValue: null,
apiObj: {
type: Function, default: () => {
}
},
params: {
type: Object, 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},
tableWidth: {type: Number, default: 400},
mode: {type: String, default: "popover"},
props: {
type: Object, default: () => {
}
}
})
const tableRef = ref(null)
const selectRef = ref(null)
let loading = ref(false)
let keyword = ref(null)
let defaultValue = ref([])
let tableData = ref([])
let pageSize = ref(config.pageSize)
let total = ref(0)
let currentPage = ref(1)
let defaultProps = ref({
label: config.props.label,
value: config.props.value,
page: config.request.page,
pageSize: config.request.pageSize,
keyword: config.request.keyword,
fields: []
})
let formData = ref({})
watch(() => props.modelValue, () => {
defaultValue.value = props.modelValue
autoCurrentLabel()
}, {deep: true})
onMounted(() => {
defaultProps.value = Object.assign(defaultProps.value, props.props);
defaultValue.value = props.modelValue
autoCurrentLabel()
})
//表格显示隐藏回调
function visibleChange(visible) {
if (visible) {
currentPage.value = 1
keyword.value = null
formData.value = {}
getData()
} else {
autoCurrentLabel()
}
}
async function getData() {
loading.value = true;
var reqData = {
[defaultProps.value.page]: currentPage.value,
[defaultProps.value.pageSize]: pageSize.value,
[defaultProps.value.keyword]: keyword.value
}
Object.assign(reqData, props.params, formData.value)
var res = await props.apiObj(reqData);
var parseData = config.parseData(res)
tableData.value = parseData.rows;
total.value = parseData.total;
loading.value = false;
//表格默认赋值
nextTick(() => {
if (props.multiple) {
defaultValue.value.forEach(row => {
var setrow = tableData.value.filter(item => item[defaultProps.value.value] === row[defaultProps.value.value])
if (setrow.length > 0) {
tableRef.value.toggleRowSelection(setrow[0], true);
}
})
} else {
var setrow = tableData.value.filter(item => item[defaultProps.value.value] === defaultValue.value[defaultProps.value.value])
tableRef.value.setCurrentRow(setrow[0]);
}
tableRef.value.setScrollTop(0)
})
}
//插糟表单提交
function formSubmit() {
currentPage.value = 1
keyword.value = null
getData()
}
//分页刷新表格
function reload() {
getData()
}
//自动模拟options赋值
function autoCurrentLabel() {
// nextTick(() => {
// if (props.multiple) {
// selectRef.value.selected.forEach(item => {
// item.currentLabel = item.value[defaultProps.value.label]
// })
// } else {
// selectRef.value.selectedLabel = defaultValue.value[defaultProps.value.label]
// }
// })
}
//表格勾选事件
function select(rows, row) {
var isSelect = rows.length && rows.indexOf(row) !== -1
if (isSelect) {
defaultValue.value.push(row)
} else {
defaultValue.value.splice(defaultValue.value.findIndex(item => item[defaultProps.value.value] == row[defaultProps.value.value]), 1)
}
autoCurrentLabel()
// 解析数据
emit('update:modelValue', config.filter(defaultValue.value, defaultProps.value.fields, props.multiple));
emit('change', config.filter(defaultValue.value, defaultProps.value.fields, props.multiple));
}
//表格全选事件
function selectAll(rows) {
var isAllSelect = rows.length > 0
if (isAllSelect) {
rows.forEach(row => {
var isHas = defaultValue.value.find(item => item[defaultProps.value.value] == row[defaultProps.value.value])
if (!isHas) {
defaultValue.value.push(row)
}
})
} else {
this.tableData.forEach(row => {
var isHas = defaultValue.value.find(item => item[defaultProps.value.value] == row[defaultProps.value.value])
if (isHas) {
defaultValue.value.splice(defaultValue.value.findIndex(item => item[defaultProps.value.value] == row[defaultProps.value.value]), 1)
}
})
}
autoCurrentLabel()
emit('update:modelValue', config.filter(defaultValue.value, defaultProps.value.fields, props.multiple));
emit('change', config.filter(defaultValue.value, defaultProps.value.fields, props.multiple));
}
function click(row) {
if (props.multiple) {
//处理多选点击行
} else {
defaultValue.value = row
selectRef.value.blur()
autoCurrentLabel()
emit('update:modelValue', config.filter(defaultValue.value, defaultProps.value.fields, props.multiple));
emit('change', config.filter(defaultValue.value, defaultProps.value.fields, props.multiple));
}
}
//tags删除后回调
function removeTag(tag) {
var row = findRowByKey(tag[defaultProps.value.value])
tableRef.value.toggleRowSelection(row, false);
emit('update:modelValue', config.filter(defaultValue.value, defaultProps.value.fields, props.multiple));
}
//清空后的回调
function clear() {
emit('update:modelValue', config.filter(defaultValue.value, defaultProps.value.fields, props.multiple));
}
// 关键值查询表格数据行
function findRowByKey(value) {
return tableData.value.find(item => item[defaultProps.value.value] === value)
}
function filterMethod(k) {
if (!k) {
keyword.value = null;
return false;
}
keyword.value = k;
getData()
}
// 触发select隐藏
function blur() {
selectRef.value.blur();
}
// 触发select显示
function focus() {
selectRef.value.focus();
}
</script>
<style scoped>
.pi-table-select__table {
padding: 12px;
}
.pi-table-select__page {
padding-top: 12px;
}
</style>