ref: 优化表格列排序组件
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, watch, computed } from 'vue';
|
import { reactive, watch, onMounted, PropType } from 'vue';
|
||||||
import { Container, Draggable } from 'vue3-smooth-dnd';
|
import { Container, Draggable } from 'vue3-smooth-dnd';
|
||||||
import useI18n from '@/hooks/useI18n';
|
import useI18n from '@/hooks/useI18n';
|
||||||
import { type ColumnsType } from 'ant-design-vue/lib/table';
|
import { type ColumnsType } from 'ant-design-vue/lib/table';
|
||||||
@@ -7,11 +7,23 @@ const { t } = useI18n();
|
|||||||
|
|
||||||
const emit = defineEmits(['update:columns-dnd']);
|
const emit = defineEmits(['update:columns-dnd']);
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
/**表格字段列,必传 */
|
/**
|
||||||
|
* 表格字段列非响应式数据,必传
|
||||||
|
*
|
||||||
|
* v-model:columns-dnd取变更的数据
|
||||||
|
*/
|
||||||
columns: {
|
columns: {
|
||||||
type: Array<any>,
|
type: Array<any>,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
/**按钮类型
|
||||||
|
* text 图标
|
||||||
|
* ghost 图标按钮带文字
|
||||||
|
*/
|
||||||
|
type: {
|
||||||
|
type: String as PropType<'text' | 'ghost'>,
|
||||||
|
default: 'text',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
/**表格字段列 */
|
/**表格字段列 */
|
||||||
@@ -19,8 +31,8 @@ const tableColumns = reactive<ColumnsType>(props.columns);
|
|||||||
|
|
||||||
/**表格字段列勾选状态 */
|
/**表格字段列勾选状态 */
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
indeterminate: true,
|
indeterminate: false,
|
||||||
checkAll: false,
|
checkAll: true,
|
||||||
columnsTitleList: tableColumns.map(s => `${s.title}`),
|
columnsTitleList: tableColumns.map(s => `${s.title}`),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -38,6 +50,7 @@ function fnTableColumnsDrop(dropResult: any) {
|
|||||||
let itemToAdd = payload;
|
let itemToAdd = payload;
|
||||||
itemToAdd = tableColumns.splice(removedIndex, 1)[0];
|
itemToAdd = tableColumns.splice(removedIndex, 1)[0];
|
||||||
tableColumns.splice(addedIndex, 0, itemToAdd);
|
tableColumns.splice(addedIndex, 0, itemToAdd);
|
||||||
|
fnUpdateColumns();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,6 +68,18 @@ function fnTableColumnsFixed(row: Record<string, any>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**表格字段列勾选字段变化 */
|
||||||
|
function fnUpdateColumns() {
|
||||||
|
let list = tableColumns.filter(s =>
|
||||||
|
state.columnsTitleList.includes(`${s.title}`)
|
||||||
|
);
|
||||||
|
// 取消全选时留第一个
|
||||||
|
if (list.length === 0) {
|
||||||
|
list = [tableColumns[0]];
|
||||||
|
}
|
||||||
|
emit('update:columns-dnd', list);
|
||||||
|
}
|
||||||
|
|
||||||
/**表格字段列勾选监听 */
|
/**表格字段列勾选监听 */
|
||||||
watch(
|
watch(
|
||||||
() => state.columnsTitleList,
|
() => state.columnsTitleList,
|
||||||
@@ -62,21 +87,13 @@ watch(
|
|||||||
const len = val.length;
|
const len = val.length;
|
||||||
state.indeterminate = !!len && len < tableColumns.length;
|
state.indeterminate = !!len && len < tableColumns.length;
|
||||||
state.checkAll = len === tableColumns.length;
|
state.checkAll = len === tableColumns.length;
|
||||||
|
fnUpdateColumns();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
/**表格字段列勾选字段变化 */
|
onMounted(() => {
|
||||||
const tableColumnsCheckList = computed(() => {
|
fnUpdateColumns();
|
||||||
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>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -99,7 +116,7 @@ emit('update:columns-dnd', tableColumnsCheckList);
|
|||||||
<template #content>
|
<template #content>
|
||||||
<a-checkbox-group
|
<a-checkbox-group
|
||||||
v-model:value="state.columnsTitleList"
|
v-model:value="state.columnsTitleList"
|
||||||
style="width: 100%; max-height: 450px; overflow-y: auto;"
|
style="width: 100%; max-height: 450px; overflow-y: auto"
|
||||||
>
|
>
|
||||||
<Container orientation="vertical" @drop="fnTableColumnsDrop">
|
<Container orientation="vertical" @drop="fnTableColumnsDrop">
|
||||||
<Draggable v-for="c in tableColumns" :key="c.title">
|
<Draggable v-for="c in tableColumns" :key="c.title">
|
||||||
@@ -121,8 +138,11 @@ emit('update:columns-dnd', tableColumnsCheckList);
|
|||||||
</Container>
|
</Container>
|
||||||
</a-checkbox-group>
|
</a-checkbox-group>
|
||||||
</template>
|
</template>
|
||||||
<a-button type="text">
|
<a-button :type="props.type" size="small">
|
||||||
<template #icon><TableOutlined /></template>
|
<template #icon><TableOutlined /></template>
|
||||||
|
<span v-if="props.type === 'ghost'">
|
||||||
|
{{ t('common.columnSetText') }}
|
||||||
|
</span>
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-popover>
|
</a-popover>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
|
|||||||
Reference in New Issue
Block a user