Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add vxe-table component #4563

Merged
merged 13 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions apps/backend-mock/api/table/list.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { faker } from '@faker-js/faker';
import { verifyAccessToken } from '~/utils/jwt-utils';
import { unAuthorizedResponse } from '~/utils/response';
anncwb marked this conversation as resolved.
Show resolved Hide resolved

function generateMockDataList(count: number) {
const dataList = [];

for (let i = 0; i < count; i++) {
const dataItem = {
id: faker.string.uuid(),
imageUrl: faker.image.avatar(),
imageUrl2: faker.image.avatar(),
open: faker.datatype.boolean(),
status: faker.helpers.arrayElement(['success', 'error', 'warning']),
productName: faker.commerce.productName(),
price: faker.commerce.price(),
anncwb marked this conversation as resolved.
Show resolved Hide resolved
currency: faker.finance.currencyCode(),
quantity: faker.number.int({ min: 1, max: 100 }),
available: faker.datatype.boolean(),
category: faker.commerce.department(),
releaseDate: faker.date.past(),
rating: faker.number.float({ min: 1, max: 5 }),
description: faker.commerce.productDescription(),
weight: faker.number.float({ min: 0.1, max: 10 }),
color: faker.color.human(),
inProduction: faker.datatype.boolean(),
tags: Array.from({ length: 3 }, () => faker.commerce.productAdjective()),
};

dataList.push(dataItem);
}

return dataList;
}

const mockData = generateMockDataList(100);

export default eventHandler(async (event) => {
const userinfo = verifyAccessToken(event);
if (!userinfo) {
return unAuthorizedResponse(event);
}

await sleep(600);

const { page, pageSize } = getQuery(event);
return usePageResponseSuccess(page as string, pageSize as string, mockData);
});
1 change: 1 addition & 0 deletions apps/backend-mock/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"start": "nitro dev"
},
"dependencies": {
"@faker-js/faker": "catalog:",
"jsonwebtoken": "catalog:",
"nitropack": "catalog:"
},
Expand Down
36 changes: 36 additions & 0 deletions apps/backend-mock/utils/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,27 @@ export function useResponseSuccess<T = any>(data: T) {
};
}

export function usePageResponseSuccess<T = any>(
page: number | string,
pageSize: number | string,
list: T[],
{ message = 'ok' } = {},
) {
const pageData = pagination(
Number.parseInt(`${page}`),
Number.parseInt(`${pageSize}`),
anncwb marked this conversation as resolved.
Show resolved Hide resolved
list,
);

return {
...useResponseSuccess({
items: pageData,
total: list.length,
}),
message,
};
anncwb marked this conversation as resolved.
Show resolved Hide resolved
}

export function useResponseError(message: string, error: any = null) {
return {
code: -1,
Expand All @@ -27,3 +48,18 @@ export function unAuthorizedResponse(event: H3Event<EventHandlerRequest>) {
setResponseStatus(event, 401);
return useResponseError('UnauthorizedException', 'Unauthorized Exception');
}

export function sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}

export function pagination<T = any>(
pageNo: number,
pageSize: number,
array: T[],
): T[] {
const offset = (pageNo - 1) * Number(pageSize);
return offset + Number(pageSize) >= array.length
? array.slice(offset)
: array.slice(offset, offset + Number(pageSize));
}
anncwb marked this conversation as resolved.
Show resolved Hide resolved
1 change: 1 addition & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"intlify",
"mkdist",
"mockjs",
"vitejs",
"noopener",
"noreferrer",
"nprogress",
Expand Down
2 changes: 0 additions & 2 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@
"dependencies": {
"@vben-core/shadcn-ui": "workspace:*",
"@vben/common-ui": "workspace:*",
"@vben/hooks": "workspace:*",
"@vben/locales": "workspace:*",
"@vben/preferences": "workspace:*",
"@vben/styles": "workspace:*",
"ant-design-vue": "catalog:",
"lucide-vue-next": "catalog:",
Expand Down
1 change: 1 addition & 0 deletions docs/src/components/common-ui/vben-form.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ useVbenForm 返回的第二个参数,是一个对象,包含了一些表单
| submitButtonOptions | 提交按钮组件参数 | `ActionButtonOptions` | - |
| showDefaultActions | 是否显示默认操作按钮 | `boolean` | `true` |
| collapsed | 是否折叠,在`是否展开,在showCollapseButton=true`时生效 | `boolean` | `false` |
| collapseTriggerResize | 折叠时,触发`resize`事件 | `boolean` | `false` |
| collapsedRows | 折叠时保持的行数 | `number` | `1` |
| commonConfig | 表单项的通用配置,每个配置都会传递到每个表单项,表单项可覆盖 | `FormCommonConfig` | - |
| schema | 表单项的每一项配置 | `FormSchema` | - |
Expand Down
5 changes: 4 additions & 1 deletion internal/tailwind-config/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,10 @@ const customColors = {
main: {
DEFAULT: 'hsl(var(--main))',
},
overlay: 'hsl(var(--overlay))',
overlay: {
content: 'hsl(var(--overlay-content))',
DEFAULT: 'hsl(var(--overlay))',
},
red: {
...createColorsPalette('red'),
foreground: 'hsl(var(--destructive-foreground))',
Expand Down
3 changes: 2 additions & 1 deletion internal/vite-config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"vite": "catalog:",
"vite-plugin-compression": "catalog:",
"vite-plugin-dts": "catalog:",
"vite-plugin-html": "catalog:"
"vite-plugin-html": "catalog:",
"vite-plugin-lazy-import": "catalog:"
}
}
1 change: 1 addition & 0 deletions internal/vite-config/src/config/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ function defineApplicationConfig(userConfigPromise?: DefineApplicationOptions) {
},
pwa: true,
pwaOptions: getDefaultPwaOptions(appTitle),
vxeTableLazyImport: true,
...envConfig,
...application,
});
Expand Down
8 changes: 8 additions & 0 deletions internal/vite-config/src/plugins/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { viteMetadataPlugin } from './inject-metadata';
import { viteLicensePlugin } from './license';
import { viteNitroMockPlugin } from './nitro-mock';
import { vitePrintPlugin } from './print';
import { viteVxeTableImportsPlugin } from './vxe-table';

/**
* 获取条件成立的 vite 插件
Expand Down Expand Up @@ -110,6 +111,7 @@ async function loadApplicationPlugins(
printInfoMap,
pwa,
pwaOptions,
vxeTableLazyImport,
...commonOptions
} = options;

Expand All @@ -135,6 +137,12 @@ async function loadApplicationPlugins(
return [await vitePrintPlugin({ infoMap: printInfoMap })];
},
},
{
condition: vxeTableLazyImport,
plugins: async () => {
return [await viteVxeTableImportsPlugin()];
},
},
{
condition: nitroMock,
plugins: async () => {
Expand Down
20 changes: 20 additions & 0 deletions internal/vite-config/src/plugins/vxe-table.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { PluginOption } from 'vite';

import { lazyImport, VxeResolver } from 'vite-plugin-lazy-import';

async function viteVxeTableImportsPlugin(): Promise<PluginOption> {
return [
lazyImport({
resolvers: [
VxeResolver({
libraryName: 'vxe-table',
}),
VxeResolver({
libraryName: 'vxe-pc-ui',
}),
],
}),
];
}

export { viteVxeTableImportsPlugin };
2 changes: 2 additions & 0 deletions internal/vite-config/src/typing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ interface ApplicationPluginOptions extends CommonPluginOptions {
pwa?: boolean;
/** pwa 插件配置 */
pwaOptions?: Partial<PwaPluginOptions>;
/** 是否开启vxe-table懒加载 */
vxeTableLazyImport?: boolean;
}

interface LibraryPluginOptions extends CommonPluginOptions {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@

/* 遮罩颜色 */
--overlay: 0deg 0% 0% / 40%;
--overlay-content: 0deg 0% 0% / 40%;

/* 基本文字大小 */
--font-size-base: 16px;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@

/* 遮罩颜色 */
--overlay: 0 0% 0% / 45%;
--overlay-light: 0 0% 95% / 45%;
--overlay-content: 0 0% 95% / 45%;

/* 基本文字大小 */
--font-size-base: 16px;
Expand Down
16 changes: 15 additions & 1 deletion packages/@core/base/icons/build.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,19 @@ import { defineBuildConfig } from 'unbuild';
export default defineBuildConfig({
clean: true,
declaration: true,
entries: ['src/index'],
entries: [
{
builder: 'mkdist',
input: './src',
loaders: ['vue'],
pattern: ['**/*.vue'],
},
{
builder: 'mkdist',
format: 'esm',
input: './src',
loaders: ['js'],
pattern: ['**/*.ts'],
},
],
});
27 changes: 27 additions & 0 deletions packages/@core/base/icons/src/components/empty.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<template>
<svg
height="41"
viewBox="0 0 64 41"
width="64"
xmlns="http://www.w3.org/2000/svg"
>
<g fill="none" fill-rule="evenodd" transform="translate(0 1)">
<ellipse
cx="32"
cy="33"
fill="hsl(var(--background-deep))"
rx="32"
ry="7"
/>
<g fill-rule="nonzero" stroke="hsl(var(--heavy))">
<path
d="M55 12.76L44.854 1.258C44.367.474 43.656 0 42.907 0H21.093c-.749 0-1.46.474-1.947 1.257L9 12.761V22h46v-9.24z"
/>
<path
d="M41.613 15.931c0-1.605.994-2.93 2.227-2.931H55v18.137C55 33.26 53.68 35 52.05 35h-40.1C10.32 35 9 33.259 9 31.137V13h11.16c1.233 0 2.227 1.323 2.227 2.928v.022c0 1.605 1.005 2.901 2.237 2.901h14.752c1.232 0 2.237-1.308 2.237-2.913v-.007z"
fill="hsl(var(--accent))"
/>
</g>
</g>
</svg>
</template>
3 changes: 2 additions & 1 deletion packages/@core/base/icons/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { default as EmptyIcon } from './components/empty.vue';
export * from './create-icon';
export * from './lucide';

export * from './lucide';
export * from '@iconify/vue';
10 changes: 6 additions & 4 deletions packages/@core/base/shared/src/constants/globals.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
/**
* @zh_CN 布局内容高度 css变量
* @en_US Layout content height
*/
/** layout content 组件的高度 */
export const CSS_VARIABLE_LAYOUT_CONTENT_HEIGHT = `--vben-content-height`;
/** layout content 组件的宽度 */
export const CSS_VARIABLE_LAYOUT_CONTENT_WIDTH = `--vben-content-width`;
/** layout header 组件的高度 */
export const CSS_VARIABLE_LAYOUT_HEADER_HEIGHT = `--vben-header-height`;
/** layout footer 组件的高度 */
export const CSS_VARIABLE_LAYOUT_FOOTER_HEIGHT = `--vben-footer-height`;

/**
* @zh_CN 默认命名空间
Expand Down
8 changes: 8 additions & 0 deletions packages/@core/base/shared/src/utils/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,11 @@ export function needsScrollbar() {
// 在其他情况下,根据 scrollHeight 和 innerHeight 比较判断
return doc.scrollHeight > window.innerHeight;
}

export function triggerWindowResize(): void {
// 创建一个新的 resize 事件
const resizeEvent = new Event('resize');

// 触发 window 的 resize 事件
window.dispatchEvent(resizeEvent);
}
2 changes: 1 addition & 1 deletion packages/@core/composables/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export * from './use-content-style';
export * from './use-is-mobile';
export * from './use-layout-style';
anncwb marked this conversation as resolved.
Show resolved Hide resolved
export * from './use-namespace';
export * from './use-priority-value';
export * from './use-scroll-lock';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { computed, onMounted, onUnmounted, ref } from 'vue';
import {
CSS_VARIABLE_LAYOUT_CONTENT_HEIGHT,
CSS_VARIABLE_LAYOUT_CONTENT_WIDTH,
CSS_VARIABLE_LAYOUT_FOOTER_HEIGHT,
CSS_VARIABLE_LAYOUT_HEADER_HEIGHT,
} from '@vben-core/shared/constants';
import {
getElementVisibleRect,
Expand All @@ -15,7 +17,7 @@ import { useCssVar, useDebounceFn } from '@vueuse/core';
/**
* @zh_CN content style
*/
function useContentStyle() {
export function useLayoutContentStyle() {
let resizeObserver: null | ResizeObserver = null;
const contentElement = ref<HTMLDivElement | null>(null);
const visibleDomRect = ref<null | VisibleDomRect>(null);
Expand All @@ -40,7 +42,7 @@ function useContentStyle() {
contentHeight.value = `${visibleDomRect.value.height}px`;
contentWidth.value = `${visibleDomRect.value.width}px`;
},
100,
16,
);

onMounted(() => {
Expand All @@ -58,4 +60,28 @@ function useContentStyle() {
return { contentElement, overlayStyle, visibleDomRect };
}

export { useContentStyle };
export function useLayoutHeaderStyle() {
const headerHeight = useCssVar(CSS_VARIABLE_LAYOUT_HEADER_HEIGHT);

return {
getLayoutHeaderHeight: () => {
return Number.parseInt(`${headerHeight.value}`, 10);
},
setLayoutHeaderHeight: (height: number) => {
headerHeight.value = `${height}px`;
},
};
}

export function useLayoutFooterStyle() {
const footerHeight = useCssVar(CSS_VARIABLE_LAYOUT_FOOTER_HEIGHT);

return {
getLayoutFooterHeight: () => {
return Number.parseInt(`${footerHeight.value}`, 10);
},
setLayoutFooterHeight: (height: number) => {
footerHeight.value = `${height}px`;
},
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ exports[`defaultPreferences immutability test > should not modify the config obj
"icpLink": "",
},
"footer": {
"enable": true,
"enable": false,
"fixed": false,
},
"header": {
Expand Down
Loading