feat: 封装xTable 组件

This commit is contained in:
xingyu 2023-01-03 10:10:51 +08:00
parent 6f8384af70
commit f831b43dec
8 changed files with 358 additions and 0 deletions

View File

@ -0,0 +1,3 @@
import XTable from './src/XTable.vue'
export { XTable }

View File

@ -0,0 +1,202 @@
<template>
<VxeGrid v-bind="getProps" ref="xGrid" :class="`${prefixCls}`" class="xtable-scrollbar">
<template #[item]="data" v-for="item in Object.keys($slots)" :key="item">
<slot :name="item" v-bind="data || {}"></slot>
</template>
</VxeGrid>
</template>
<script lang="ts" setup name="XTable">
import { computed, PropType, ref, unref, useAttrs, watch } from 'vue'
import { SizeType, VxeGridInstance } from 'vxe-table'
import { useAppStore } from '@/store/modules/app'
import { useDesign } from '@/hooks/web/useDesign'
import { XTableProps } from './type'
import { isBoolean, isFunction } from '@/utils/is'
const appStore = useAppStore()
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('x-vxe-table')
const attrs = useAttrs()
const emit = defineEmits(['register'])
const props = defineProps({
options: {
type: Object as PropType<XTableProps>,
default: () => {}
}
})
const innerProps = ref<Partial<XTableProps>>()
const getProps = computed(() => {
const options = innerProps.value || props.options
options.size = currentSize as any
options.height = 700
getColumnsConfig(options)
getProxyConfig(options)
getPageConfig(options)
getToolBarConfig(options)
// console.log(options);
return {
...options,
...attrs
}
})
const xGrid = ref<VxeGridInstance>() // Grid Ref
watch(
() => appStore.getIsDark,
() => {
if (appStore.getIsDark == true) {
import('./style/dark.scss')
}
if (appStore.getIsDark == false) {
import('./style/light.scss')
}
},
{ immediate: true }
)
const currentSize = computed(() => {
let resSize: SizeType = 'small'
const appsize = appStore.getCurrentSize
switch (appsize) {
case 'large':
resSize = 'medium'
break
case 'default':
resSize = 'small'
break
case 'small':
resSize = 'mini'
break
}
return resSize
})
const reload = () => {
const g = unref(xGrid)
if (!g) {
return
}
g.commitProxy('query')
}
const getSearchData = () => {
const g = unref(xGrid)
if (!g) {
return
}
const queryParams = Object.assign({}, JSON.parse(JSON.stringify(g.getProxyInfo()?.form)))
return queryParams
}
let proxyForm = false
// columns
const getColumnsConfig = (options: XTableProps) => {
const { allSchemas } = options
if (!allSchemas) return
if (allSchemas.printSchema) {
options.printConfig = {
columns: allSchemas.printSchema
}
}
if (allSchemas.formSchema) {
proxyForm = true
options.formConfig = {
enabled: true,
titleWidth: 100,
titleAlign: 'right',
items: allSchemas.searchSchema
}
}
if (allSchemas.tableSchema) {
options.columns = allSchemas.tableSchema
}
}
//
const getProxyConfig = (options: XTableProps) => {
const { getListApi, proxyConfig, data } = options
if (proxyConfig || data) return
if (getListApi && isFunction(getListApi)) {
options.proxyConfig = {
seq: true, //
form: proxyForm, // reload
props: { result: 'list', total: 'total' },
ajax: {
query: async ({ page, form }) => {
let queryParams: any = Object.assign({}, JSON.parse(JSON.stringify(form)))
if (options.params) {
queryParams = Object.assign(queryParams, options.params)
}
queryParams.pageSize = page.currentPage
queryParams.page = page.pageSize
return new Promise(async (resolve) => {
resolve(await getListApi(queryParams))
})
}
}
}
}
}
//
const getPageConfig = (options: XTableProps) => {
const { pagination, pagerConfig } = options
if (pagerConfig) return
if (pagination) {
if (isBoolean(pagination)) {
options.pagerConfig = {
border: false, //
background: true, //
perfect: false, //
pageSize: 10, //
pagerCount: 7, //
autoHidden: false, //
pageSizes: [5, 10, 20, 30, 50, 100], //
layouts: [
'PrevJump',
'PrevPage',
'JumpNumber',
'NextPage',
'NextJump',
'Sizes',
'FullJump',
'Total'
]
}
return
}
options.pagerConfig = pagination
}
}
// tool bar
const getToolBarConfig = (options: XTableProps) => {
const { toolBar, toolbarConfig } = options
if (toolbarConfig) return
if (toolBar) {
if (!isBoolean(toolBar)) {
options.toolbarConfig = toolBar
return
}
} else {
options.toolbarConfig = {
slots: { buttons: 'toolbar_buttons' }
}
}
}
const setProps = (prop: Partial<XTableProps>) => {
innerProps.value = { ...unref(innerProps), ...prop }
}
defineExpose({ reload, Ref: xGrid, getSearchData })
emit('register', { reload, getSearchData, setProps })
</script>
<style lang="scss">
@import './style/index.scss';
</style>

View File

@ -0,0 +1,81 @@
// 修改样式变量
//@import 'vxe-table/styles/variable.scss';
/*font*/
$vxe-font-color: #e5e7eb;
// $vxe-font-size: 14px !default;
// $vxe-font-size-medium: 16px !default;
// $vxe-font-size-small: 14px !default;
// $vxe-font-size-mini: 12px !default;
/*color*/
$vxe-primary-color: #409eff !default;
$vxe-success-color: #67c23a !default;
$vxe-info-color: #909399 !default;
$vxe-warning-color: #e6a23c !default;
$vxe-danger-color: #f56c6c !default;
$vxe-disabled-color: #bfbfbf !default;
$vxe-primary-disabled-color: #c0c4cc !default;
/*loading*/
$vxe-loading-color: $vxe-primary-color !default;
$vxe-loading-background-color: #1d1e1f !default;
$vxe-loading-z-index: 999 !default;
/*icon*/
$vxe-icon-font-family: Verdana, Arial, Tahoma !default;
$vxe-icon-background-color: #e5e7eb !default;
/*toolbar*/
$vxe-toolbar-background-color: #1d1e1f !default;
$vxe-toolbar-button-border: #dcdfe6 !default;
$vxe-toolbar-custom-active-background-color: #d9dadb !default;
$vxe-toolbar-panel-background-color: #e5e7eb !default;
$vxe-table-font-color: #e5e7eb;
$vxe-table-header-background-color: #1d1e1f;
$vxe-table-body-background-color: #141414;
$vxe-table-row-striped-background-color: #1d1d1d;
$vxe-table-row-hover-background-color: #1d1e1f;
$vxe-table-row-hover-striped-background-color: #1e1e1e;
$vxe-table-footer-background-color: #1d1e1f;
$vxe-table-row-current-background-color: #302d2d;
$vxe-table-column-current-background-color: #302d2d;
$vxe-table-column-hover-background-color: #302d2d;
$vxe-table-row-hover-current-background-color: #302d2d;
$vxe-table-row-checkbox-checked-background-color: #3e3c37 !default;
$vxe-table-row-hover-checkbox-checked-background-color: #615a4a !default;
$vxe-table-menu-background-color: #1d1e1f;
$vxe-table-border-width: 1px !default;
$vxe-table-border-color: #4c4d4f !default;
$vxe-table-fixed-left-scrolling-box-shadow: 8px 0px 10px -5px rgba(0, 0, 0, 0.12) !default;
$vxe-table-fixed-right-scrolling-box-shadow: -8px 0px 10px -5px rgba(0, 0, 0, 0.12) !default;
$vxe-form-background-color: #141414;
/*pager*/
$vxe-pager-background-color: #1d1e1f !default;
$vxe-pager-perfect-background-color: #262727 !default;
$vxe-pager-perfect-button-background-color: #a7a3a3 !default;
$vxe-input-background-color: #141414;
$vxe-input-border-color: #4c4d4f !default;
$vxe-select-option-hover-background-color: #262626 !default;
$vxe-select-panel-background-color: #141414 !default;
$vxe-select-empty-color: #262626 !default;
$vxe-optgroup-title-color: #909399 !default;
/*button*/
$vxe-button-default-background-color: #262626;
$vxe-button-dropdown-panel-background-color: #141414;
/*modal*/
$vxe-modal-header-background-color: #141414;
$vxe-modal-body-background-color: #141414;
$vxe-modal-border-color: #3b3b3b;
/*pulldown*/
$vxe-pulldown-panel-background-color: #262626 !default;
@import 'vxe-table/styles/index';

View File

@ -0,0 +1,6 @@
@import 'vxe-table/styles/variable.scss';
@import 'vxe-table/styles/modules.scss';
// @import './theme/light.scss';
i {
border-color: initial;
}

View File

@ -0,0 +1,16 @@
// 修改样式变量
// /*font*/
// $vxe-font-size: 12px !default;
// $vxe-font-size-medium: 16px !default;
// $vxe-font-size-small: 14px !default;
// $vxe-font-size-mini: 12px !default;
/*color*/
$vxe-primary-color: #409eff !default;
$vxe-success-color: #67c23a !default;
$vxe-info-color: #909399 !default;
$vxe-warning-color: #e6a23c !default;
$vxe-danger-color: #f56c6c !default;
$vxe-disabled-color: #bfbfbf !default;
$vxe-primary-disabled-color: #c0c4cc !default;
@import 'vxe-table/styles/index.scss';

View File

@ -0,0 +1,20 @@
import { CrudSchema } from '@/hooks/web/useCrudSchemas'
import type { VxeGridProps, VxeGridPropTypes } from 'vxe-table'
export type XTableProps<D = any> = VxeGridProps<D> & {
allSchemas?: CrudSchema
getListApi?: Function
deleteApi?: Function
exportListApi?: Function
params?: any
pagination?: boolean | VxeGridPropTypes.PagerConfig
toolBar?: boolean | VxeGridPropTypes.ToolbarConfig
afterFetch?: Function
}
export type XColumns = VxeGridPropTypes.Columns
export type VxeTableColumn = {
field: string
title?: string
children?: VxeTableColumn[]
} & Recordable

View File

@ -4,6 +4,7 @@ import { Form } from '@/components/Form'
import { Table } from '@/components/Table'
import { Search } from '@/components/Search'
import { XModal } from '@/components/XModal'
import { XTable } from '@/components/XTable'
import { XButton, XTextButton } from '@/components/XButton'
import { DictTag } from '@/components/DictTag'
import { ContentWrap } from '@/components/ContentWrap'
@ -15,6 +16,7 @@ export const setupGlobCom = (app: App<Element>): void => {
app.component('Table', Table)
app.component('Search', Search)
app.component('XModal', XModal)
app.component('XTable', XTable)
app.component('XButton', XButton)
app.component('XTextButton', XTextButton)
app.component('DictTag', DictTag)

View File

@ -0,0 +1,28 @@
import { ref, unref } from 'vue'
import { XTableProps } from '@/components/XTable/src/type'
export interface tableMethod {
reload: () => void
setProps: (props: XTableProps) => void
}
export function useXTable(props: XTableProps): [Function, tableMethod] {
const tableRef = ref<Nullable<tableMethod>>(null)
function register(instance) {
tableRef.value = instance
props && instance.setProps(props)
}
function getInstance(): tableMethod {
const table = unref(tableRef)
if (!table) {
console.error('表格实例不存在')
}
return table as tableMethod
}
const methods: tableMethod = {
reload: () => getInstance().reload(),
setProps: (props) => getInstance().setProps(props)
}
return [register, methods]
}