Skip to content

Commit

Permalink
feat: 加上自定义vxeTable
Browse files Browse the repository at this point in the history
  • Loading branch information
jiayun zhang committed Sep 20, 2022
1 parent e571cf8 commit 2206494
Show file tree
Hide file tree
Showing 7 changed files with 1,017 additions and 0 deletions.
284 changes: 284 additions & 0 deletions src/components/meVxeTable/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
<template>
<div class="me-vxe-table" :class="meClass">
<div v-if="toolbar" class="me-vxe-toolbar">
<div v-if="$slots.search" v-show="showSearch" class="me-vxe-toolbar-search">
<slot name="search"></slot>
</div>
<div class="me-vxe-toolbar-menu">
<div class="me-vxe-toolbar-buttons">
<el-button v-if="_.vnode.props.onRefresh" @click="$emit('refresh')">
<mel-icon-refresh />
</el-button>
<el-button v-if="_.vnode.props.onAdd" type="primary" @click="$emit('add')">
<mel-icon-plus />
</el-button>
<slot name="buttons"></slot>
</div>
<div class="me-vxe-toolbar-tools">
<el-input
v-if="_.vnode.props.onQuickSearch"
v-model="searchText"
:placeholder="$t(quickSearchPlaceholder!)"
prefix-icon="mel-icon-search"
@change="$emit('quickSearch', searchText)"
/>
<el-button-group>
<el-popover v-if="customColumn" :teleported="false" placement="bottom" trigger="click" width="auto">
<template #reference>
<el-button icon="mel-icon-grid" :title="$t('自定义列')" />
</template>
<template #default>
<el-scrollbar max-height="300px" class="popover-scrollbar-y">
<el-tree
node-key="id"
:default-checked-keys="defaultChecked"
:data="collectColumn"
default-expand-all
:props="{ label: (item:VxeTableDefines.ColumnInfo)=>item.type==='seq'?'#':item.title, children: 'children' }"
show-checkbox
@check-change="checkChange"
/>
</el-scrollbar>
</template>
</el-popover>
<el-popover
v-if="exportMenu"
pure
placement="bottom"
trigger="click"
popper-class="me-vxe-exportmenu-popover el-dropdown__popper"
>
<template #reference>
<el-button icon="mel-icon-download" :title="$t('导出')" />
</template>
<template #default>
<ul class="el-dropdown-menu">
<li
v-for="item in exportMenu"
:key="item.label"
class="el-dropdown-menu__item"
@click="handleExport(item.handle, item.filename ?? name!)"
>
{{ item.label }}
</li>
</ul>
</template>
</el-popover>
<el-button v-if="print" icon="mel-icon-printer" :title="$t('打印')" @click="printTable()" />
<slot name="tools"></slot>
</el-button-group>
<el-button v-if="$slots.search" :title="$t('更多筛选')" @click="showSearch = !showSearch">
<mel-icon-search></mel-icon-search>
</el-button>
</div>
</div>
</div>
<div class="me-vxe-body">
<vxe-table ref="vxeTableRef" v-bind="$attrs">
<slot></slot>
<template #empty>
<slot name="empty"></slot>
</template>
</vxe-table>
</div>
</div>
</template>
<script lang="ts">
import './install';
import { ComponentOptionsMixin, ExtractPropTypes, PropType } from 'vue';
import {
VXEComponent,
VxeTableDefines,
VxeTableEventProps,
VxeTableInstance,
VxeTableProps,
VxeTablePropTypes,
} from 'vxe-table';
import { debounce } from 'lodash-es';
const props = {
meClass: [String, Array as PropType<string[]>],
name: {
type: String,
default: 'meVxeTable',
},
exportMenu: {
type: Array as PropType<
{
label: string;
filename?: string;
handle: (vxeTable: VxeTableInstance, filename: string) => void | 'csv' | 'html' | 'xml' | 'txt';
}[]
>,
default: () => [
{ label: 'csv', handle: 'csv' },
{ label: 'html', handle: 'html' },
{ label: 'xml', handle: 'xml' },
{ label: 'txt', handle: 'txt' },
],
},
print: {
type: [Object as PropType<VxeTablePropTypes.PrintConfig>, Boolean],
default: () => ({}),
},
customColumn: {
type: Boolean,
default: true,
},
defaultShowSearch: {
type: Boolean,
default: false,
},
toolbar: {
type: Boolean,
default: true,
},
quickSearchPlaceholder: {
type: String,
default: '快捷搜索',
},
};
const emits = {
quickSearch(searchText: string) {
//快捷搜索
return true;
},
refresh() {
return true;
},
add() {
return true;
},
};
export default defineComponent<
ComponentProps<VXEComponent<VxeTableProps, VxeTableEventProps>> & Partial<ExtractPropTypes<typeof props>>,
Record<string, any>,
Record<string, any>,
Record<string, any>,
Record<string, any>,
ComponentOptionsMixin,
ComponentOptionsMixin,
typeof emits
>({
name: 'MeVxeTable',
inheritAttrs: false,
props: props as any,
emits,
setup(props, { slots, expose }) {
const vxeTableRef = ref<VxeTableInstance>();
const searchText = ref('');
const showSearch = ref(props.defaultShowSearch);
const collectColumn = ref([] as VxeTableDefines.ColumnInfo[]);
const defaultChecked = ref([] as string[]);
const refreshColumn = debounce(() => {
vxeTableRef.value?.refreshColumn();
}, 500);
const checkChange = (data: VxeTableDefines.ColumnInfo, is: boolean) => {
data.visible = is;
refreshColumn();
};
onMounted(() => {
nextTick(() => {
const { collectColumn: origionCollectColumn, fullColumn } = vxeTableRef.value!.getTableColumn();
collectColumn.value = origionCollectColumn;
defaultChecked.value = fullColumn.reduce((previousValue, currentValue) => {
if (currentValue.visible) {
previousValue.push(currentValue.id);
}
return previousValue;
}, [] as string[]);
});
});
expose({ vxeTable: vxeTableRef });
return {
vxeTableRef,
collectColumn,
defaultChecked,
checkChange,
handleExport: (
handle: (vxeTable: VxeTableInstance, filename: string) => void | 'csv' | 'html' | 'xml' | 'txt',
filename: string,
) => {
if (typeof handle === 'string') {
vxeTableRef.value!.exportData({
type: handle,
filename,
data: vxeTableRef.value!.getCheckboxRecords().length ? vxeTableRef.value!.getCheckboxRecords() : undefined,
});
} else {
handle(vxeTableRef.value!, filename);
}
},
printTable: () => {
vxeTableRef.value!.print(
Object.assign(
{
sheetName: props.name,
data: vxeTableRef.value!.getCheckboxRecords().length
? vxeTableRef.value!.getCheckboxRecords()
: undefined,
},
props.print === true,
),
);
},
searchText,
showSearch,
};
},
});
</script>
<style lang="scss" scoped>
.me-vxe-table {
.me-vxe-toolbar {
margin-top: -12px;
margin-bottom: 12px;
.me-vxe-toolbar-search {
margin-top: 12px;
}
.me-vxe-toolbar-menu {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
.me-vxe-toolbar-buttons {
margin-top: 12px;
}
.me-vxe-toolbar-tools {
margin-top: 12px;
display: flex;
align-items: center;
> div,
> span,
> button {
margin-left: 12px;
}
> div:first-child,
> span:first-child,
> button:first-child {
margin-left: 0;
}
> .el-button-group {
flex-shrink: 0;
}
}
}
}
}
:global(.me-vxe-exportmenu-popover) {
width: max-content !important;
min-width: unset !important;
}
:global(.me-vxe-exportmenu-popover .el-dropdown-menu__item:not(.is-disabled):hover) {
background-color: var(--el-dropdown-menuItem-hover-fill);
color: var(--el-dropdown-menuItem-hover-color);
}
</style>
11 changes: 11 additions & 0 deletions src/components/meVxeTable/install.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { app } from '@/app';
import VXETable from 'vxe-table';
import VXETablePluginElement from 'vxe-table-plugin-element';
import './style.scss';
import 'vxe-table-plugin-element/dist/style.css';
VXETable.use(VXETablePluginElement);
VXETable.setup({
// 对组件内置的提示语进行国际化翻译
i18n: app.config.globalProperties.$t,
});
app.use(VXETable);
Loading

0 comments on commit 2206494

Please sign in to comment.