255 lines
7.1 KiB
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>
|