Merge branch 'develop'
This commit is contained in:
@@ -0,0 +1,261 @@
|
||||
<template>
|
||||
<div class="table-header">
|
||||
<div class="left">
|
||||
<slot name="left"></slot>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="btn" @click="refresh">
|
||||
<i class="iconfont-sys"></i>
|
||||
</div>
|
||||
|
||||
<ElDropdown @command="handleTableSizeChange">
|
||||
<div class="btn">
|
||||
<i class="iconfont-sys"></i>
|
||||
</div>
|
||||
<template #dropdown>
|
||||
<ElDropdownMenu>
|
||||
<div v-for="item in tableSizeOptions" :key="item.value" class="table-size-btn-item">
|
||||
<ElDropdownItem
|
||||
:key="item.value"
|
||||
:command="item.value"
|
||||
:class="{ 'is-selected': tableSize === item.value }"
|
||||
>
|
||||
{{ item.label }}
|
||||
</ElDropdownItem>
|
||||
</div>
|
||||
</ElDropdownMenu>
|
||||
</template>
|
||||
</ElDropdown>
|
||||
|
||||
<div class="btn" @click="toggleFullScreen">
|
||||
<i class="iconfont-sys">{{ isFullScreen ? '' : '' }}</i>
|
||||
</div>
|
||||
|
||||
<!-- 列设置 -->
|
||||
<ElPopover placement="bottom" trigger="click">
|
||||
<template #reference>
|
||||
<div class="btn"><i class="iconfont-sys" style="font-size: 17px"></i> </div>
|
||||
</template>
|
||||
<div>
|
||||
<VueDraggable v-model="columns">
|
||||
<div v-for="item in columns" :key="item.prop || item.type" class="column-option">
|
||||
<div class="drag-icon">
|
||||
<i class="iconfont-sys"></i>
|
||||
</div>
|
||||
<ElCheckbox v-model="item.checked" :disabled="item.disabled">{{
|
||||
item.label || (item.type === 'selection' ? t('table.selection') : '')
|
||||
}}</ElCheckbox>
|
||||
</div>
|
||||
</VueDraggable>
|
||||
</div>
|
||||
</ElPopover>
|
||||
<!-- 其他设置 -->
|
||||
<ElPopover placement="bottom" trigger="click">
|
||||
<template #reference>
|
||||
<div class="btn">
|
||||
<i class="iconfont-sys" style="font-size: 17px"></i>
|
||||
</div>
|
||||
</template>
|
||||
<div>
|
||||
<ElCheckbox v-if="showZebra" v-model="isZebra" :value="true">{{
|
||||
t('table.zebra')
|
||||
}}</ElCheckbox>
|
||||
<ElCheckbox v-if="showBorder" v-model="isBorder" :value="true">{{
|
||||
t('table.border')
|
||||
}}</ElCheckbox>
|
||||
<ElCheckbox v-if="showHeaderBackground" v-model="isHeaderBackground" :value="true">{{
|
||||
t('table.headerBackground')
|
||||
}}</ElCheckbox>
|
||||
</div>
|
||||
</ElPopover>
|
||||
<slot name="right"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { TableSizeEnum } from '@/enums/formEnum'
|
||||
import { useTableStore } from '@/store/modules/table'
|
||||
import { ElPopover, ElCheckbox } from 'element-plus'
|
||||
import { VueDraggable } from 'vue-draggable-plus'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
defineProps({
|
||||
// 斑马纹
|
||||
showZebra: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 边框
|
||||
showBorder: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 表头背景
|
||||
showHeaderBackground: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
})
|
||||
|
||||
const columns = defineModel<ColumnOption[]>('columns', { required: true })
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'refresh'): void
|
||||
}>()
|
||||
|
||||
interface ColumnOption {
|
||||
label?: string
|
||||
prop?: string
|
||||
type?: string
|
||||
width?: string | number
|
||||
fixed?: boolean | 'left' | 'right'
|
||||
sortable?: boolean
|
||||
filters?: any[]
|
||||
filterMethod?: (value: any, row: any) => boolean
|
||||
filterPlacement?: string
|
||||
disabled?: boolean
|
||||
checked?: boolean
|
||||
}
|
||||
|
||||
const tableSizeOptions = [
|
||||
{ value: TableSizeEnum.SMALL, label: t('table.sizeOptions.small') },
|
||||
{ value: TableSizeEnum.DEFAULT, label: t('table.sizeOptions.default') },
|
||||
{ value: TableSizeEnum.LARGE, label: t('table.sizeOptions.large') }
|
||||
]
|
||||
|
||||
const tableStore = useTableStore()
|
||||
const { tableSize, isZebra, isBorder, isHeaderBackground } = storeToRefs(tableStore)
|
||||
|
||||
const refresh = () => {
|
||||
emit('refresh')
|
||||
}
|
||||
|
||||
// 表格大小
|
||||
const handleTableSizeChange = (command: TableSizeEnum) => {
|
||||
useTableStore().setTableSize(command)
|
||||
}
|
||||
|
||||
const isFullScreen = ref(false)
|
||||
|
||||
// 全屏
|
||||
const toggleFullScreen = () => {
|
||||
const el = document.querySelector('#table-full-screen')
|
||||
if (!el) return
|
||||
isFullScreen.value = !isFullScreen.value
|
||||
|
||||
el.classList.toggle('el-full-screen')
|
||||
}
|
||||
|
||||
// 监听ESC键退出全屏
|
||||
onMounted(() => {
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape' && isFullScreen.value) {
|
||||
toggleFullScreen()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
document.removeEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape' && isFullScreen.value) {
|
||||
toggleFullScreen()
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.table-size-btn-item) {
|
||||
.el-dropdown-menu__item {
|
||||
margin-bottom: 3px !important;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
.el-dropdown-menu__item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.is-selected) {
|
||||
background-color: rgba(var(--art-gray-200-rgb), 0.8) !important;
|
||||
}
|
||||
|
||||
.table-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin-left: 10px;
|
||||
color: var(--art-gray-700);
|
||||
cursor: pointer;
|
||||
background-color: rgba(var(--art-gray-200-rgb), 0.8);
|
||||
border-radius: 6px;
|
||||
transition: color 0.3s;
|
||||
transition: all 0.3s;
|
||||
|
||||
i {
|
||||
font-size: 16px;
|
||||
color: var(--art-gray-700);
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(var(--art-gray-300-rgb), 0.75);
|
||||
|
||||
i {
|
||||
color: var(--art-gray-800);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.column-option) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.drag-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 18px;
|
||||
margin-right: 8px;
|
||||
color: var(--art-gray-500);
|
||||
cursor: move;
|
||||
|
||||
i {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: $device-phone) {
|
||||
.table-header {
|
||||
flex-direction: column;
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
|
||||
.btn {
|
||||
margin-right: 10px;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user