feat: 表格字段列排序可选组件
This commit is contained in:
156
src/components/TableColumnsDnd/index.vue
Normal file
156
src/components/TableColumnsDnd/index.vue
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, watch, computed } from 'vue';
|
||||||
|
import { Container, Draggable } from 'vue3-smooth-dnd';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
import { type ColumnsType } from 'ant-design-vue/lib/table';
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:columns-dnd']);
|
||||||
|
const props = defineProps({
|
||||||
|
/**表格字段列,必传 */
|
||||||
|
columns: {
|
||||||
|
type: Array<any>,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**表格字段列 */
|
||||||
|
const tableColumns = reactive<ColumnsType>(props.columns);
|
||||||
|
|
||||||
|
/**表格字段列勾选状态 */
|
||||||
|
const state = reactive({
|
||||||
|
indeterminate: true,
|
||||||
|
checkAll: false,
|
||||||
|
columnsTitleList: tableColumns.map(s => `${s.title}`),
|
||||||
|
});
|
||||||
|
|
||||||
|
/**表格字段列全选操作 */
|
||||||
|
function fnTableColumnsCheckAllChange(e: any) {
|
||||||
|
const checked = e.target.checked;
|
||||||
|
state.indeterminate = false;
|
||||||
|
state.columnsTitleList = checked ? tableColumns.map(s => `${s.title}`) : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表格字段列拖拽操作 */
|
||||||
|
function fnTableColumnsDrop(dropResult: any) {
|
||||||
|
const { removedIndex, addedIndex, payload } = dropResult;
|
||||||
|
if (removedIndex !== null && addedIndex !== null) {
|
||||||
|
let itemToAdd = payload;
|
||||||
|
itemToAdd = tableColumns.splice(removedIndex, 1)[0];
|
||||||
|
tableColumns.splice(addedIndex, 0, itemToAdd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表格字段列固定操作 */
|
||||||
|
function fnTableColumnsFixed(row: Record<string, any>) {
|
||||||
|
if (row.fixed === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const optTitle = t('common.operate');
|
||||||
|
if (row.title === optTitle) {
|
||||||
|
const optFixed = row.fixed === 'right';
|
||||||
|
row.fixed = optFixed ? false : 'right';
|
||||||
|
} else {
|
||||||
|
row.fixed = !row.fixed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表格字段列勾选监听 */
|
||||||
|
watch(
|
||||||
|
() => state.columnsTitleList,
|
||||||
|
val => {
|
||||||
|
const len = val.length;
|
||||||
|
state.indeterminate = !!len && len < tableColumns.length;
|
||||||
|
state.checkAll = len === tableColumns.length;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**表格字段列勾选字段变化 */
|
||||||
|
const tableColumnsCheckList = computed(() => {
|
||||||
|
let list = tableColumns.filter(s =>
|
||||||
|
state.columnsTitleList.includes(`${s.title}`)
|
||||||
|
);
|
||||||
|
// 取消全选时留最后一个
|
||||||
|
if (list.length === 0) {
|
||||||
|
list = [tableColumns[tableColumns.length - 1]];
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
});
|
||||||
|
emit('update:columns-dnd', tableColumnsCheckList);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<a-tooltip>
|
||||||
|
<template #title>
|
||||||
|
{{ t('common.columnSetText') }}
|
||||||
|
</template>
|
||||||
|
<a-popover trigger="click" placement="bottomRight">
|
||||||
|
<template #title>
|
||||||
|
<div class="table-column-setting-title">
|
||||||
|
<a-checkbox
|
||||||
|
v-model:checked="state.checkAll"
|
||||||
|
:indeterminate="state.indeterminate"
|
||||||
|
@change="fnTableColumnsCheckAllChange"
|
||||||
|
>
|
||||||
|
{{ t('common.columnSetTitle') }}
|
||||||
|
</a-checkbox>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #content>
|
||||||
|
<a-checkbox-group
|
||||||
|
v-model:value="state.columnsTitleList"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<Container orientation="vertical" @drop="fnTableColumnsDrop">
|
||||||
|
<Draggable v-for="c in tableColumns" :key="c.title">
|
||||||
|
<div class="table-column-setting-list-item">
|
||||||
|
<HolderOutlined class="anticon" />
|
||||||
|
<a-checkbox :value="c.title">
|
||||||
|
{{ c.title }}
|
||||||
|
</a-checkbox>
|
||||||
|
<a-button
|
||||||
|
v-if="c.fixed !== undefined"
|
||||||
|
size="small"
|
||||||
|
:type="c.fixed ? 'primary' : 'dashed'"
|
||||||
|
@click="fnTableColumnsFixed(c)"
|
||||||
|
>
|
||||||
|
<template #icon><FlagOutlined /></template>
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
</Draggable>
|
||||||
|
</Container>
|
||||||
|
</a-checkbox-group>
|
||||||
|
</template>
|
||||||
|
<a-button type="text">
|
||||||
|
<template #icon><TableOutlined /></template>
|
||||||
|
</a-button>
|
||||||
|
</a-popover>
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.table-column-setting-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
height: 32px;
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-column-setting-list-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-column-setting-list-item > .anticon {
|
||||||
|
padding-right: 8px;
|
||||||
|
cursor: move;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-column-setting-list-item .ant-checkbox-wrapper {
|
||||||
|
flex: 1;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user