docs: add vxe-table doc (#4807)

* docs: init vxe-table demos

* style: fix vxe-table index.scss import error

* docs: fix vxe-table style & theme toggle problem

* docs: add rest demos

* docs: add vxe-table demo desc

* fix: add maximumFileSizeToCacheInBytes to fix build error

* fix: fix vxe-table set-theme build error

* docs: fix vitepress ssr render problem

* docs: add some tips for vitepress compatibility
pull/48/MERGE
Arthur Darkstone 2024-11-06 21:44:02 +08:00 committed by GitHub
parent 6b54cb7563
commit 33ce4d3cf3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 1529 additions and 36 deletions

View File

@ -156,6 +156,7 @@ function pwa(): PwaOptions {
registerType: 'autoUpdate',
workbox: {
globPatterns: ['**/*.{css,js,html,svg,png,ico,txt,woff2}'],
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024,
},
};
}

View File

@ -32,6 +32,21 @@ watch(
() => nextTick(() => initZoom()),
);
function setVxeTheme(name?: string) {
const theme = !name || name === 'default' ? 'light' : name;
if (typeof document !== 'undefined') {
const documentElement = document.documentElement;
if (documentElement) {
documentElement.dataset.vxeUiTheme = theme;
}
}
}
watch(isDark, (dark) => {
setVxeTheme(dark ? 'dark' : 'light');
});
// initPreferences({
// namespace: 'docs',
// });

View File

@ -1,7 +1,12 @@
// https://vitepress.dev/guide/custom-theme
import type { EnhanceAppContext, Theme } from 'vitepress';
import { h } from 'vue';
import { useVbenForm } from '@vben/common-ui';
import { NolebaseGitChangelogPlugin } from '@nolebase/vitepress-plugin-git-changelog/client';
import { Button, Image } from 'ant-design-vue';
import DefaultTheme from 'vitepress/theme';
import { DemoPreview } from '../components';
@ -15,11 +20,71 @@ import 'virtual:group-icons.css';
import '@nolebase/vitepress-plugin-git-changelog/client/style.css';
export default {
enhanceApp(ctx: EnhanceAppContext) {
async enhanceApp(ctx: EnhanceAppContext) {
const { app } = ctx;
app.component('VbenContributors', VbenContributors);
app.component('DemoPreview', DemoPreview);
app.use(NolebaseGitChangelogPlugin);
if (!import.meta.env.SSR) {
const plugin = await import('@vben/plugins/vxe-table');
plugin.setupVbenVxeTable({
configVxeTable: (vxeUI) => {
vxeUI.setConfig({
grid: {
align: 'center',
border: false,
columnConfig: {
resizable: true,
},
minHeight: 180,
proxyConfig: {
autoLoad: true,
response: {
result: 'items',
total: 'total',
list: 'items',
},
showActiveMsg: true,
showResponseMsg: false,
},
round: true,
showOverflow: true,
size: 'small',
},
});
// 表格配置项可以用 cellRender: { name: 'CellImage' },
vxeUI.renderer.add('CellImage', {
renderDefault(_renderOpts, params) {
const { column, row } = params;
return h(Image, { src: row[column.field] } as any);
},
});
// 表格配置项可以用 cellRender: { name: 'CellLink' },
vxeUI.renderer.add('CellLink', {
renderDefault(renderOpts) {
const { props } = renderOpts;
return h(
Button,
{ size: 'small', type: 'link' },
{ default: () => props?.text },
);
},
});
// 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化
// vxeUI.formats.add
},
useVbenForm,
});
app.component('VbenVxeGrid', plugin.VbenVxeGrid);
app.provide('useVbenVxeGrid', plugin.useVbenVxeGrid);
}
// 百度统计
initHmPlugin();
},

View File

@ -14,6 +14,7 @@
"@vben-core/shadcn-ui": "workspace:*",
"@vben/common-ui": "workspace:*",
"@vben/locales": "workspace:*",
"@vben/plugins": "workspace:*",
"@vben/styles": "workspace:*",
"ant-design-vue": "catalog:",
"lucide-vue-next": "catalog:",
@ -25,6 +26,7 @@
"@nolebase/vitepress-plugin-git-changelog": "catalog:",
"@vben/vite-config": "workspace:*",
"@vite-pwa/vitepress": "catalog:",
"sass": "^1.80.6",
"vitepress": "catalog:",
"vue": "catalog:"
}

View File

@ -1 +1,2 @@
export * from './form';
export * from './vxe-table';

View File

@ -0,0 +1 @@
export type * from '@vben/plugins/vxe-table';

View File

@ -4,4 +4,113 @@ outline: deep
# Vben Vxe Table 表格
文档待补充,如果需要使用,可先行查看 vxe-table 文档和 示例代码,内部有部分注释。
框架提供的Table 列表组件基于 [vxe-table](https://vxetable.cn/v4/#/grid/api?apiKey=grid),结合`Vben Form 表单`进行了二次封装。
其中,表头的 **表单搜索** 部分采用了`Vben Form表单`,表格主体部分使用了`vxe-grid`组件,支持表格的分页、排序、筛选等功能。
> 如果文档内没有参数说明,可以尝试在在线示例或者在 [vxe-grid 官方API 文档](https://vxetable.cn/v4/#/grid/api?apiKey=grid) 内寻找
::: info 写在前面
如果你觉得现有组件的封装不够理想,或者不完全符合你的需求,大可以直接使用原生组件,亦或亲手封装一个适合的组件。框架提供的组件并非束缚,使用与否,完全取决于你的需求与自由。
:::
::: tip README
下方示例代码中, 出现的 `inject<UseVbenVxeGrid>` 是为了适配文档内的示例,实际使用时直接从 `'@vben/plugins/vxe-table'` 引入即可。
```typescript
import { useVbenVxeGrid } from '@vben/plugins/vxe-table';
```
:::
## 基础表格
使用 `useVbenVxeGrid` 创建最基础的表格。
<DemoPreview dir="demos/vben-vxe-table/basic" />
## 远程加载
通过指定 `proxyConfig.ajax``query` 方法,可以实现远程加载数据。
<DemoPreview dir="demos/vben-vxe-table/remote" />
## 树形表格
树形表格,的数据源为扁平结构,可以指定`treeConfig`配置项,实现树形表格。
```typescript
treeConfig: {
transform: true, // 指定表格为树形表格
parentField: 'parentId', // 父节点字段名
rowField: 'id', // 行数据字段名
},
```
<DemoPreview dir="demos/vben-vxe-table/tree" />
## 固定表头/列
列固定可选参数: `'left' | 'right' | '' | null`
<DemoPreview dir="demos/vben-vxe-table/fixed" />
## 自定义单元格
自定义单元格有两种实现方式
- 通过 `slots` 插槽
- 通过 `customCell` 自定义单元格,但是要先添加渲染器
```typescript
// 表格配置项可以用 cellRender: { name: 'CellImage' },
vxeUI.renderer.add('CellImage', {
renderDefault(_renderOpts, params) {
const { column, row } = params;
return h(Image, { src: row[column.field] } as any); // 注意此处的Image 组件来源于Antd需要自行引入,否则会使用js的Image类
},
});
// 表格配置项可以用 cellRender: { name: 'CellLink' },
vxeUI.renderer.add('CellLink', {
renderDefault(renderOpts) {
const { props } = renderOpts;
return h(
Button,
{ size: 'small', type: 'link' },
{ default: () => props?.text },
);
},
});
```
<DemoPreview dir="demos/vben-vxe-table/custom-cell" />
## 搜索表单
**表单搜索** 部分采用了`Vben Form 表单`,参考 [Vben Form 表单文档](/components/common-ui/vben-form)。
<DemoPreview dir="demos/vben-vxe-table/form" />
## 单元格编辑
通过指定`editConfig.mode`为`cell`,可以实现单元格编辑。
<DemoPreview dir="demos/vben-vxe-table/edit-cell" />
## 行编辑
通过指定`editConfig.mode`为`row`,可以实现行编辑。
<DemoPreview dir="demos/vben-vxe-table/edit-row" />
## 虚拟滚动
通过 scroll-y.enabled 与 scroll-y.gt 组合开启,其中 enabled 为总开关gt 是指当总行数大于指定行数时自动开启。
> 参考 [vxe-table 官方文档 - 虚拟滚动](https://vxetable.cn/v4/#/component/grid/scroll/vertical)。
<DemoPreview dir="demos/vben-vxe-table/virtual" />

View File

@ -0,0 +1,93 @@
<script lang="ts" setup>
import type {
UseVbenVxeGrid,
VxeGridListeners,
VxeGridProps,
} from '#/adapter/vxe-table';
import { inject } from 'vue';
import { Button, message } from 'ant-design-vue';
import { MOCK_TABLE_DATA } from '../table-data';
interface RowType {
address: string;
age: number;
id: number;
name: string;
nickname: string;
role: string;
}
const useVbenVxeGrid = inject<UseVbenVxeGrid>(
'useVbenVxeGrid',
) as UseVbenVxeGrid;
const gridOptions: VxeGridProps<RowType> = {
columns: [
{ title: '序号', type: 'seq', width: 50 },
{ field: 'name', title: 'Name' },
{ field: 'age', sortable: true, title: 'Age' },
{ field: 'nickname', title: 'Nickname' },
{ field: 'role', title: 'Role' },
{ field: 'address', showOverflow: true, title: 'Address' },
],
data: MOCK_TABLE_DATA,
pagerConfig: {
enabled: false,
},
sortConfig: {
multiple: true,
},
};
const gridEvents: VxeGridListeners<RowType> = {
cellClick: ({ row }) => {
message.info(`cell-click: ${row.name}`);
},
};
const [Grid, gridApi] = useVbenVxeGrid({ gridEvents, gridOptions });
const showBorder = gridApi.useStore((state) => state.gridOptions?.border);
const showStripe = gridApi.useStore((state) => state.gridOptions?.stripe);
function changeBorder() {
gridApi.setGridOptions({
border: !showBorder.value,
});
}
function changeStripe() {
gridApi.setGridOptions({
stripe: !showStripe.value,
});
}
function changeLoading() {
gridApi.setLoading(true);
setTimeout(() => {
gridApi.setLoading(false);
}, 2000);
}
</script>
<template>
<!-- 此处的`vp-raw` 是为了适配文档的展示效果实际使用时不需要 -->
<div class="vp-raw w-full">
<Grid>
<template #toolbar-tools>
<Button class="mr-2" type="primary" @click="changeBorder">
{{ showBorder ? '隐藏' : '显示' }}边框
</Button>
<Button class="mr-2" type="primary" @click="changeLoading">
显示loading
</Button>
<Button class="mr-2" type="primary" @click="changeStripe">
{{ showStripe ? '隐藏' : '显示' }}斑马纹
</Button>
</template>
</Grid>
</div>
</template>

View File

@ -0,0 +1,109 @@
<script lang="ts" setup>
import type { UseVbenVxeGrid, VxeGridProps } from '#/adapter/vxe-table';
import { inject } from 'vue';
import { Button, Image, Switch, Tag } from 'ant-design-vue';
import { getExampleTableApi } from '../mock-api';
interface RowType {
category: string;
color: string;
id: string;
imageUrl: string;
open: boolean;
price: string;
productName: string;
releaseDate: string;
status: 'error' | 'success' | 'warning';
}
const useVbenVxeGrid = inject<UseVbenVxeGrid>(
'useVbenVxeGrid',
) as UseVbenVxeGrid;
const gridOptions: VxeGridProps<RowType> = {
checkboxConfig: {
highlight: true,
labelField: 'name',
},
columns: [
{ title: '序号', type: 'seq', width: 50 },
{ field: 'category', title: 'Category', width: 100 },
{
field: 'imageUrl',
slots: { default: 'image-url' },
title: 'Image',
width: 100,
},
{
cellRender: { name: 'CellImage' },
field: 'imageUrl2',
title: 'Render Image',
width: 130,
},
{
field: 'open',
slots: { default: 'open' },
title: 'Open',
width: 100,
},
{
field: 'status',
slots: { default: 'status' },
title: 'Status',
width: 100,
},
{ field: 'color', title: 'Color', width: 100 },
{ field: 'productName', title: 'Product Name', width: 200 },
{ field: 'price', title: 'Price', width: 100 },
{
field: 'releaseDate',
formatter: 'formatDateTime',
title: 'Date',
width: 200,
},
{
cellRender: { name: 'CellLink', props: { text: '编辑' } },
field: 'action',
fixed: 'right',
title: '操作',
width: 120,
},
],
keepSource: true,
pagerConfig: {},
proxyConfig: {
ajax: {
query: async ({ page }) => {
return await getExampleTableApi({
page: page.currentPage,
pageSize: page.pageSize,
});
},
},
},
};
const [Grid] = useVbenVxeGrid({ gridOptions });
</script>
<template>
<div class="vp-raw w-full">
<Grid>
<template #image-url="{ row }">
<Image :src="row.imageUrl" height="30" width="30" />
</template>
<template #open="{ row }">
<Switch v-model:checked="row.open" />
</template>
<template #status="{ row }">
<Tag :color="row.color">{{ row.status }}</Tag>
</template>
<template #action>
<Button type="link">编辑</Button>
</template>
</Grid>
</div>
</template>

View File

@ -0,0 +1,59 @@
<script lang="ts" setup>
import type { UseVbenVxeGrid, VxeGridProps } from '#/adapter/vxe-table';
import { inject } from 'vue';
import { getExampleTableApi } from '../mock-api';
interface RowType {
category: string;
color: string;
id: string;
price: string;
productName: string;
releaseDate: string;
}
const useVbenVxeGrid = inject<UseVbenVxeGrid>(
'useVbenVxeGrid',
) as UseVbenVxeGrid;
const gridOptions: VxeGridProps<RowType> = {
columns: [
{ title: '序号', type: 'seq', width: 50 },
{ editRender: { name: 'input' }, field: 'category', title: 'Category' },
{ editRender: { name: 'input' }, field: 'color', title: 'Color' },
{
editRender: { name: 'input' },
field: 'productName',
title: 'Product Name',
},
{ field: 'price', title: 'Price' },
{ field: 'releaseDate', formatter: 'formatDateTime', title: 'Date' },
],
editConfig: {
mode: 'cell',
trigger: 'click',
},
pagerConfig: {},
proxyConfig: {
ajax: {
query: async ({ page }) => {
return await getExampleTableApi({
page: page.currentPage,
pageSize: page.pageSize,
});
},
},
},
showOverflow: true,
};
const [Grid] = useVbenVxeGrid({ gridOptions });
</script>
<template>
<div class="vp-raw w-full">
<Grid />
</div>
</template>

View File

@ -0,0 +1,96 @@
<script lang="ts" setup>
import type { UseVbenVxeGrid, VxeGridProps } from '#/adapter/vxe-table';
import { inject } from 'vue';
import { Button, message } from 'ant-design-vue';
import { getExampleTableApi } from '../mock-api';
interface RowType {
category: string;
color: string;
id: string;
price: string;
productName: string;
releaseDate: string;
}
const useVbenVxeGrid = inject<UseVbenVxeGrid>(
'useVbenVxeGrid',
) as UseVbenVxeGrid;
const gridOptions: VxeGridProps<RowType> = {
columns: [
{ title: '序号', type: 'seq', width: 50 },
{ editRender: { name: 'input' }, field: 'category', title: 'Category' },
{ editRender: { name: 'input' }, field: 'color', title: 'Color' },
{
editRender: { name: 'input' },
field: 'productName',
title: 'Product Name',
},
{ field: 'price', title: 'Price' },
{ field: 'releaseDate', formatter: 'formatDateTime', title: 'Date' },
{ slots: { default: 'action' }, title: '操作' },
],
editConfig: {
mode: 'row',
trigger: 'click',
},
pagerConfig: {},
proxyConfig: {
ajax: {
query: async ({ page }) => {
return await getExampleTableApi({
page: page.currentPage,
pageSize: page.pageSize,
});
},
},
},
showOverflow: true,
};
const [Grid, gridApi] = useVbenVxeGrid({ gridOptions });
function hasEditStatus(row: RowType) {
return gridApi.grid?.isEditByRow(row);
}
function editRowEvent(row: RowType) {
gridApi.grid?.setEditRow(row);
}
async function saveRowEvent(row: RowType) {
await gridApi.grid?.clearEdit();
gridApi.setLoading(true);
setTimeout(() => {
gridApi.setLoading(false);
message.success({
content: `保存成功category=${row.category}`,
});
}, 600);
}
const cancelRowEvent = (_row: RowType) => {
gridApi.grid?.clearEdit();
};
</script>
<template>
<div class="vp-raw w-full">
<Grid>
<template #action="{ row }">
<template v-if="hasEditStatus(row)">
<Button type="link" @click="saveRowEvent(row)"></Button>
<Button type="link" @click="cancelRowEvent(row)"></Button>
</template>
<template v-else>
<Button type="link" @click="editRowEvent(row)"></Button>
</template>
</template>
</Grid>
</div>
</template>

View File

@ -0,0 +1,71 @@
<script lang="ts" setup>
import type { UseVbenVxeGrid, VxeGridProps } from '#/adapter/vxe-table';
import { inject } from 'vue';
import { Button } from 'ant-design-vue';
import { getExampleTableApi } from '../mock-api';
interface RowType {
category: string;
color: string;
id: string;
price: string;
productName: string;
releaseDate: string;
}
const useVbenVxeGrid = inject<UseVbenVxeGrid>(
'useVbenVxeGrid',
) as UseVbenVxeGrid;
const gridOptions: VxeGridProps<RowType> = {
columns: [
{ fixed: 'left', title: '序号', type: 'seq', width: 50 },
{ field: 'category', title: 'Category', width: 300 },
{ field: 'color', title: 'Color', width: 300 },
{ field: 'productName', title: 'Product Name', width: 300 },
{ field: 'price', title: 'Price', width: 300 },
{
field: 'releaseDate',
formatter: 'formatDateTime',
title: 'DateTime',
width: 500,
},
{
field: 'action',
fixed: 'right',
slots: { default: 'action' },
title: '操作',
width: 120,
},
],
pagerConfig: {},
proxyConfig: {
ajax: {
query: async ({ page }) => {
return await getExampleTableApi({
page: page.currentPage,
pageSize: page.pageSize,
});
},
},
},
rowConfig: {
isHover: true,
},
};
const [Grid] = useVbenVxeGrid({ gridOptions });
</script>
<template>
<div class="vp-raw w-full">
<Grid>
<template #action>
<Button type="link">编辑</Button>
</template>
</Grid>
</div>
</template>

View File

@ -0,0 +1,124 @@
<script lang="ts" setup>
import type { VbenFormProps } from '#/adapter/form';
import type { UseVbenVxeGrid, VxeGridProps } from '#/adapter/vxe-table';
import { inject } from 'vue';
import { message } from 'ant-design-vue';
import { getExampleTableApi } from '../mock-api';
interface RowType {
category: string;
color: string;
id: string;
price: string;
productName: string;
releaseDate: string;
}
const useVbenVxeGrid = inject<UseVbenVxeGrid>(
'useVbenVxeGrid',
) as UseVbenVxeGrid;
const formOptions: VbenFormProps = {
//
collapsed: false,
schema: [
{
component: 'Input',
componentProps: {
placeholder: 'Please enter category',
},
defaultValue: '1',
fieldName: 'category',
label: 'Category',
},
{
component: 'Input',
componentProps: {
placeholder: 'Please enter productName',
},
fieldName: 'productName',
label: 'ProductName',
},
{
component: 'Input',
componentProps: {
placeholder: 'Please enter price',
},
fieldName: 'price',
label: 'Price',
},
{
component: 'Select',
componentProps: {
allowClear: true,
options: [
{
label: 'Color1',
value: '1',
},
{
label: 'Color2',
value: '2',
},
],
placeholder: '请选择',
},
fieldName: 'color',
label: 'Color',
},
{
component: 'DatePicker',
fieldName: 'datePicker',
label: 'Date',
},
],
//
showCollapseButton: true,
submitButtonOptions: {
content: '查询',
},
//
submitOnEnter: false,
};
const gridOptions: VxeGridProps<RowType> = {
checkboxConfig: {
highlight: true,
labelField: 'name',
},
columns: [
{ title: '序号', type: 'seq', width: 50 },
{ align: 'left', title: 'Name', type: 'checkbox', width: 100 },
{ field: 'category', title: 'Category' },
{ field: 'color', title: 'Color' },
{ field: 'productName', title: 'Product Name' },
{ field: 'price', title: 'Price' },
{ field: 'releaseDate', formatter: 'formatDateTime', title: 'Date' },
],
keepSource: true,
pagerConfig: {},
proxyConfig: {
ajax: {
query: async ({ page }, formValues) => {
message.success(`Query params: ${JSON.stringify(formValues)}`);
return await getExampleTableApi({
page: page.currentPage,
pageSize: page.pageSize,
...formValues,
});
},
},
},
};
const [Grid] = useVbenVxeGrid({ formOptions, gridOptions });
</script>
<template>
<div class="vp-raw w-full">
<Grid />
</div>
</template>

View File

@ -0,0 +1,36 @@
import { MOCK_API_DATA } from './table-data';
export namespace DemoTableApi {
export interface PageFetchParams {
[key: string]: any;
page: number;
pageSize: number;
}
}
export function sleep(time = 1000) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(true);
}, time);
});
}
/**
*
*/
async function getExampleTableApi(params: DemoTableApi.PageFetchParams) {
return new Promise<{ items: any; total: number }>((resolve) => {
const { page, pageSize } = params;
const items = MOCK_API_DATA.slice((page - 1) * pageSize, page * pageSize);
sleep(1000).then(() => {
resolve({
total: items.length,
items,
});
});
});
}
export { getExampleTableApi };

View File

@ -0,0 +1,115 @@
<script lang="ts" setup>
import type { UseVbenVxeGrid, VxeGridProps } from '#/adapter/vxe-table';
import { inject } from 'vue';
import { Button } from 'ant-design-vue';
import { type DemoTableApi } from '../mock-api';
import { MOCK_API_DATA } from '../table-data';
interface RowType {
category: string;
color: string;
id: string;
price: string;
productName: string;
releaseDate: string;
}
const useVbenVxeGrid = inject<UseVbenVxeGrid>(
'useVbenVxeGrid',
) as UseVbenVxeGrid;
//
// const MOCK_TREE_TABLE_DATA = [
// {
// date: '2020-08-01',
// id: 10_000,
// name: 'Test1',
// parentId: null,
// size: 1024,
// type: 'mp3',
// },
// ]
const sleep = (time = 1000) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(true);
}, time);
});
};
/**
* 获取示例表格数据
*/
async function getExampleTableApi(params: DemoTableApi.PageFetchParams) {
return new Promise<{ items: any; total: number }>((resolve) => {
const { page, pageSize } = params;
const items = MOCK_API_DATA.slice((page - 1) * pageSize, page * pageSize);
sleep(1000).then(() => {
resolve({
total: items.length,
items,
});
});
});
}
const gridOptions: VxeGridProps<RowType> = {
checkboxConfig: {
highlight: true,
labelField: 'name',
},
columns: [
{ title: '序号', type: 'seq', width: 50 },
{ align: 'left', title: 'Name', type: 'checkbox', width: 100 },
{ field: 'category', title: 'Category' },
{ field: 'color', title: 'Color' },
{ field: 'productName', title: 'Product Name' },
{ field: 'price', title: 'Price' },
{ field: 'releaseDate', formatter: 'formatDateTime', title: 'DateTime' },
],
exportConfig: {},
// height: 'auto', // auto
keepSource: true,
proxyConfig: {
ajax: {
query: async ({ page }) => {
return await getExampleTableApi({
page: page.currentPage,
pageSize: page.pageSize,
});
},
},
},
toolbarConfig: {
custom: true,
export: true,
// import: true,
refresh: true,
zoom: true,
},
};
const [Grid, gridApi] = useVbenVxeGrid({
gridOptions,
});
</script>
<template>
<div class="vp-raw w-full">
<Grid>
<template #toolbar-tools>
<Button class="mr-2" type="primary" @click="() => gridApi.query()">
刷新当前页面
</Button>
<Button type="primary" @click="() => gridApi.reload()">
刷新并返回第一页
</Button>
</template>
</Grid>
</div>
</template>

View File

@ -0,0 +1,384 @@
interface TableRowData {
address: string;
age: number;
id: number;
name: string;
nickname: string;
role: string;
}
const roles = ['User', 'Admin', 'Manager', 'Guest'];
export const MOCK_TABLE_DATA: TableRowData[] = (() => {
const data: TableRowData[] = [];
for (let i = 0; i < 10; i++) {
data.push({
address: `New York${i}`,
age: i + 1,
id: i,
name: `Test${i}`,
nickname: `Test${i}`,
role: roles[Math.floor(Math.random() * roles.length)] as string,
});
}
return data;
})();
export const MOCK_TREE_TABLE_DATA = [
{
date: '2020-08-01',
id: 10_000,
name: 'Test1',
parentId: null,
size: 1024,
type: 'mp3',
},
{
date: '2021-04-01',
id: 10_050,
name: 'Test2',
parentId: null,
size: 0,
type: 'mp4',
},
{
date: '2020-03-01',
id: 24_300,
name: 'Test3',
parentId: 10_050,
size: 1024,
type: 'avi',
},
{
date: '2021-04-01',
id: 20_045,
name: 'Test4',
parentId: 24_300,
size: 600,
type: 'html',
},
{
date: '2021-04-01',
id: 10_053,
name: 'Test5',
parentId: 24_300,
size: 0,
type: 'avi',
},
{
date: '2021-10-01',
id: 24_330,
name: 'Test6',
parentId: 10_053,
size: 25,
type: 'txt',
},
{
date: '2020-01-01',
id: 21_011,
name: 'Test7',
parentId: 10_053,
size: 512,
type: 'pdf',
},
{
date: '2021-06-01',
id: 22_200,
name: 'Test8',
parentId: 10_053,
size: 1024,
type: 'js',
},
{
date: '2020-11-01',
id: 23_666,
name: 'Test9',
parentId: null,
size: 2048,
type: 'xlsx',
},
{
date: '2021-06-01',
id: 23_677,
name: 'Test10',
parentId: 23_666,
size: 1024,
type: 'js',
},
{
date: '2021-06-01',
id: 23_671,
name: 'Test11',
parentId: 23_677,
size: 1024,
type: 'js',
},
{
date: '2021-06-01',
id: 23_672,
name: 'Test12',
parentId: 23_677,
size: 1024,
type: 'js',
},
{
date: '2021-06-01',
id: 23_688,
name: 'Test13',
parentId: 23_666,
size: 1024,
type: 'js',
},
{
date: '2021-06-01',
id: 23_681,
name: 'Test14',
parentId: 23_688,
size: 1024,
type: 'js',
},
{
date: '2021-06-01',
id: 23_682,
name: 'Test15',
parentId: 23_688,
size: 1024,
type: 'js',
},
{
date: '2020-10-01',
id: 24_555,
name: 'Test16',
parentId: null,
size: 224,
type: 'avi',
},
{
date: '2021-06-01',
id: 24_566,
name: 'Test17',
parentId: 24_555,
size: 1024,
type: 'js',
},
{
date: '2021-06-01',
id: 24_577,
name: 'Test18',
parentId: 24_555,
size: 1024,
type: 'js',
},
];
export const MOCK_API_DATA = [
{
available: true,
category: 'Computers',
color: 'purple',
currency: 'NAD',
description:
'Ergonomic executive chair upholstered in bonded black leather and PVC padded seat and back for all-day comfort and support',
id: '45a613df-227a-4907-a89f-4a7f1252ca0c',
imageUrl: 'https://avatars.githubusercontent.com/u/62715097',
imageUrl2: 'https://avatars.githubusercontent.com/u/75395683',
inProduction: false,
open: true,
price: '48.89',
productName: 'Handcrafted Steel Salad',
quantity: 70,
rating: 3.780_582_329_574_367,
releaseDate: '2024-09-09T04:06:57.793Z',
status: 'error',
tags: ['Bespoke', 'Handmade', 'Luxurious'],
weight: 1.031_015_671_912_002_5,
},
{
available: true,
category: 'Toys',
color: 'green',
currency: 'CZK',
description:
'The Nagasaki Lander is the trademarked name of several series of Nagasaki sport bikes, that started with the 1984 ABC800J',
id: 'd02e5ee9-bc98-4de2-98fa-25a6567ecc19',
imageUrl: 'https://avatars.githubusercontent.com/u/51512330',
imageUrl2: 'https://avatars.githubusercontent.com/u/58698113',
inProduction: false,
open: false,
price: '68.15',
productName: 'Generic Cotton Gloves',
quantity: 3,
rating: 1.681_749_367_682_703_3,
releaseDate: '2024-06-16T09:00:36.806Z',
status: 'warning',
tags: ['Rustic', 'Handcrafted', 'Recycled'],
weight: 9.601_076_149_300_575,
},
{
available: true,
category: 'Beauty',
color: 'teal',
currency: 'OMR',
description:
'The Apollotech B340 is an affordable wireless mouse with reliable connectivity, 12 months battery life and modern design',
id: '2b72521c-225c-4e64-8030-611b76b10b37',
imageUrl: 'https://avatars.githubusercontent.com/u/50300075',
imageUrl2: 'https://avatars.githubusercontent.com/u/36541691',
inProduction: true,
open: true,
price: '696.94',
productName: 'Gorgeous Soft Ball',
quantity: 50,
rating: 2.361_581_777_372_057_5,
releaseDate: '2024-06-03T13:24:19.809Z',
status: 'warning',
tags: ['Gorgeous', 'Ergonomic', 'Licensed'],
weight: 8.882_340_049_286_19,
},
{
available: true,
category: 'Games',
color: 'silver',
currency: 'SOS',
description:
'Carbonite web goalkeeper gloves are ergonomically designed to give easy fit',
id: 'bafab694-3801-452c-b102-9eb519bd1143',
imageUrl: 'https://avatars.githubusercontent.com/u/89827115',
imageUrl2: 'https://avatars.githubusercontent.com/u/55952747',
inProduction: false,
open: false,
price: '553.84',
productName: 'Bespoke Soft Computer',
quantity: 29,
rating: 2.176_412_873_760_271_7,
releaseDate: '2024-09-17T12:16:27.034Z',
status: 'error',
tags: ['Elegant', 'Rustic', 'Recycled'],
weight: 9.653_285_869_978_038,
},
{
available: true,
category: 'Toys',
color: 'indigo',
currency: 'BIF',
description:
'Andy shoes are designed to keeping in mind durability as well as trends, the most stylish range of shoes & sandals',
id: 'bf6dea6b-2a55-441d-8773-937e03d99389',
imageUrl: 'https://avatars.githubusercontent.com/u/21431092',
imageUrl2: 'https://avatars.githubusercontent.com/u/3771350',
inProduction: true,
open: true,
price: '237.39',
productName: 'Handcrafted Cotton Mouse',
quantity: 54,
rating: 4.363_265_388_265_461,
releaseDate: '2023-10-23T13:42:34.947Z',
status: 'error',
tags: ['Unbranded', 'Handmade', 'Generic'],
weight: 9.513_203_612_535_571,
},
{
available: false,
category: 'Tools',
color: 'violet',
currency: 'TZS',
description:
'New ABC 13 9370, 13.3, 5th Gen CoreA5-8250U, 8GB RAM, 256GB SSD, power UHD Graphics, OS 10 Home, OS Office A & J 2016',
id: '135ba6ab-32ee-4989-8189-5cfa658ef970',
imageUrl: 'https://avatars.githubusercontent.com/u/29946092',
imageUrl2: 'https://avatars.githubusercontent.com/u/23842994',
inProduction: false,
open: false,
price: '825.25',
productName: 'Awesome Bronze Ball',
quantity: 94,
rating: 4.251_159_804_726_753,
releaseDate: '2023-12-30T07:31:43.464Z',
status: 'warning',
tags: ['Handmade', 'Elegant', 'Unbranded'],
weight: 2.247_473_385_732_636_8,
},
{
available: true,
category: 'Automotive',
color: 'teal',
currency: 'BOB',
description: 'The Football Is Good For Training And Recreational Purposes',
id: '652ef256-7d4e-48b7-976c-7afaa781ea92',
imageUrl: 'https://avatars.githubusercontent.com/u/2531904',
imageUrl2: 'https://avatars.githubusercontent.com/u/15215990',
inProduction: false,
open: false,
price: '780.49',
productName: 'Oriental Rubber Pants',
quantity: 70,
rating: 2.636_323_417_377_916,
releaseDate: '2024-02-23T23:30:49.628Z',
status: 'success',
tags: ['Unbranded', 'Elegant', 'Unbranded'],
weight: 4.812_965_858_018_838,
},
{
available: false,
category: 'Garden',
color: 'plum',
currency: 'LRD',
description:
'The slim & simple Maple Gaming Keyboard from Dev Byte comes with a sleek body and 7- Color RGB LED Back-lighting for smart functionality',
id: '3ea24798-6589-40cc-85f0-ab78752244a0',
imageUrl: 'https://avatars.githubusercontent.com/u/23165285',
imageUrl2: 'https://avatars.githubusercontent.com/u/14595665',
inProduction: false,
open: true,
price: '583.85',
productName: 'Handcrafted Concrete Hat',
quantity: 15,
rating: 1.371_600_527_752_802_7,
releaseDate: '2024-03-02T19:40:50.255Z',
status: 'error',
tags: ['Rustic', 'Sleek', 'Ergonomic'],
weight: 4.926_949_366_405_728_4,
},
{
available: false,
category: 'Industrial',
color: 'salmon',
currency: 'AUD',
description:
'The Apollotech B340 is an affordable wireless mouse with reliable connectivity, 12 months battery life and modern design',
id: '997113dd-f6e4-4acc-9790-ef554c7498d1',
imageUrl: 'https://avatars.githubusercontent.com/u/49021914',
imageUrl2: 'https://avatars.githubusercontent.com/u/4690621',
inProduction: true,
open: false,
price: '67.99',
productName: 'Generic Rubber Bacon',
quantity: 68,
rating: 4.129_840_682_128_08,
releaseDate: '2023-12-17T01:40:25.415Z',
status: 'error',
tags: ['Oriental', 'Small', 'Handcrafted'],
weight: 1.080_114_331_801_906_4,
},
{
available: false,
category: 'Tools',
color: 'sky blue',
currency: 'NOK',
description:
'The Nagasaki Lander is the trademarked name of several series of Nagasaki sport bikes, that started with the 1984 ABC800J',
id: 'f697a250-6cb2-46c8-b0f7-871ab1f2fa8d',
imageUrl: 'https://avatars.githubusercontent.com/u/95928385',
imageUrl2: 'https://avatars.githubusercontent.com/u/47588244',
inProduction: false,
open: false,
price: '613.89',
productName: 'Gorgeous Frozen Ball',
quantity: 55,
rating: 1.646_947_205_998_534_6,
releaseDate: '2024-10-13T12:31:04.929Z',
status: 'warning',
tags: ['Handmade', 'Unbranded', 'Unbranded'],
weight: 9.430_690_557_758_114,
},
];

View File

@ -0,0 +1,84 @@
<script lang="ts" setup>
import type { UseVbenVxeGrid, VxeGridProps } from '#/adapter/vxe-table';
import { inject } from 'vue';
import { Button } from 'ant-design-vue';
import { MOCK_TREE_TABLE_DATA } from '../table-data';
interface RowType {
date: string;
id: number;
name: string;
parentId: null | number;
size: number;
type: string;
}
const useVbenVxeGrid = inject<UseVbenVxeGrid>(
'useVbenVxeGrid',
) as UseVbenVxeGrid;
//
// const MOCK_TREE_TABLE_DATA = [
// {
// date: '2020-08-01',
// id: 10_000,
// name: 'Test1',
// parentId: null,
// size: 1024,
// type: 'mp3',
// },
// {
// date: '2021-04-01',
// id: 10_050,
// name: 'Test2',
// parentId: 10_000,
// size: 0,
// type: 'mp4',
// },
// ];
const gridOptions: VxeGridProps<RowType> = {
columns: [
{ type: 'seq', width: 70 },
{ field: 'name', minWidth: 300, title: 'Name', treeNode: true },
{ field: 'size', title: 'Size' },
{ field: 'type', title: 'Type' },
{ field: 'date', title: 'Date' },
],
data: MOCK_TREE_TABLE_DATA,
pagerConfig: {
enabled: false,
},
treeConfig: {
parentField: 'parentId',
rowField: 'id',
transform: true,
},
};
const [Grid, gridApi] = useVbenVxeGrid({ gridOptions });
const expandAll = () => {
gridApi.grid?.setAllTreeExpand(true);
};
const collapseAll = () => {
gridApi.grid?.setAllTreeExpand(false);
};
</script>
<template>
<div class="vp-raw h-[300px] w-full">
<Grid>
<template #toolbar-tools>
<Button class="mr-2" type="primary" @click="expandAll">
展开全部
</Button>
<Button type="primary" @click="collapseAll"> </Button>
</template>
</Grid>
</div>
</template>

View File

@ -0,0 +1,66 @@
<script lang="ts" setup>
import type { UseVbenVxeGrid, VxeGridProps } from '#/adapter/vxe-table';
import { inject, onMounted } from 'vue';
interface RowType {
id: number;
name: string;
role: string;
sex: string;
}
const useVbenVxeGrid = inject<UseVbenVxeGrid>(
'useVbenVxeGrid',
) as UseVbenVxeGrid;
const gridOptions: VxeGridProps<RowType> = {
columns: [
{ type: 'seq', width: 70 },
{ field: 'name', title: 'Name' },
{ field: 'role', title: 'Role' },
{ field: 'sex', title: 'Sex' },
],
data: [],
height: 'auto',
pagerConfig: {
enabled: false,
},
scrollY: {
enabled: true,
gt: 0,
},
showOverflow: true,
};
const [Grid, gridApi] = useVbenVxeGrid({ gridOptions });
//
const loadList = (size = 200) => {
try {
const dataList: RowType[] = [];
for (let i = 0; i < size; i++) {
dataList.push({
id: 10_000 + i,
name: `Test${i}`,
role: 'Developer',
sex: '男',
});
}
gridApi.setGridOptions({ data: dataList });
} catch (error) {
console.error('Failed to load data:', error);
// Implement user-friendly error handling
}
};
onMounted(() => {
loadList(1000);
});
</script>
<template>
<div class="vp-raw h-[500px] w-full">
<Grid />
</div>
</template>

View File

@ -1,4 +1,7 @@
export { setupVbenVxeTable } from './init';
export * from './use-vxe-grid';
export { default as VbenVxeGrid } from './use-vxe-grid.vue';
export * from 'vxe-pc-ui/styles/all.scss';
export type { VxeGridListeners, VxeGridProps } from 'vxe-table';
export * from 'vxe-table/styles/all.scss';

View File

@ -41,3 +41,5 @@ export function useVbenVxeGrid(options: VxeGridProps) {
return [Grid, extendedApi] as const;
}
export type UseVbenVxeGrid = typeof useVbenVxeGrid;

View File

@ -539,10 +539,10 @@ importers:
version: link:scripts/vsh
'@vitejs/plugin-vue':
specifier: 'catalog:'
version: 5.1.4(vite@5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.79.5)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3))
version: 5.1.4(vite@5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.80.6)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3))
'@vitejs/plugin-vue-jsx':
specifier: 'catalog:'
version: 4.0.1(vite@5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.79.5)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3))
version: 4.0.1(vite@5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.80.6)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3))
'@vue/test-utils':
specifier: 'catalog:'
version: 2.4.6
@ -584,13 +584,13 @@ importers:
version: 5.6.3
unbuild:
specifier: 'catalog:'
version: 3.0.0-rc.11(sass@1.79.5)(typescript@5.6.3)(vue-tsc@2.1.10(typescript@5.6.3))
version: 3.0.0-rc.11(sass@1.80.6)(typescript@5.6.3)(vue-tsc@2.1.10(typescript@5.6.3))
vite:
specifier: 'catalog:'
version: 5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.79.5)(terser@5.36.0)
version: 5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.80.6)(terser@5.36.0)
vitest:
specifier: 'catalog:'
version: 2.1.4(@types/node@22.8.7)(happy-dom@15.8.3)(less@4.2.0)(sass@1.79.5)(terser@5.36.0)
version: 2.1.4(@types/node@22.8.7)(happy-dom@15.8.3)(less@4.2.0)(sass@1.80.6)(terser@5.36.0)
vue:
specifier: ^3.5.12
version: 3.5.12(typescript@5.6.3)
@ -818,6 +818,9 @@ importers:
'@vben/locales':
specifier: workspace:*
version: link:../packages/locales
'@vben/plugins':
specifier: workspace:*
version: link:../packages/effects/plugins
'@vben/styles':
specifier: workspace:*
version: link:../packages/styles
@ -839,16 +842,19 @@ importers:
devDependencies:
'@nolebase/vitepress-plugin-git-changelog':
specifier: 'catalog:'
version: 2.8.1(@algolia/client-search@5.12.0)(@types/node@22.8.7)(async-validator@4.2.5)(axios@1.7.7)(change-case@5.4.4)(nprogress@0.2.0)(postcss@8.4.47)(qrcode@1.5.4)(sass@1.79.5)(search-insights@2.17.2)(sortablejs@1.15.3)(terser@5.36.0)(typescript@5.6.3)
version: 2.8.1(@algolia/client-search@5.12.0)(@types/node@22.8.7)(async-validator@4.2.5)(axios@1.7.7)(change-case@5.4.4)(nprogress@0.2.0)(postcss@8.4.47)(qrcode@1.5.4)(sass@1.80.6)(search-insights@2.17.2)(sortablejs@1.15.3)(terser@5.36.0)(typescript@5.6.3)
'@vben/vite-config':
specifier: workspace:*
version: link:../internal/vite-config
'@vite-pwa/vitepress':
specifier: 'catalog:'
version: 0.5.3(vite-plugin-pwa@0.20.5(vite@5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.79.5)(terser@5.36.0))(workbox-build@7.3.0)(workbox-window@7.3.0))
version: 0.5.3(vite-plugin-pwa@0.20.5(vite@5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.80.6)(terser@5.36.0))(workbox-build@7.3.0)(workbox-window@7.3.0))
sass:
specifier: ^1.80.6
version: 1.80.6
vitepress:
specifier: 'catalog:'
version: 1.4.5(@algolia/client-search@5.12.0)(@types/node@22.8.7)(async-validator@4.2.5)(axios@1.7.7)(change-case@5.4.4)(less@4.2.0)(nprogress@0.2.0)(postcss@8.4.47)(qrcode@1.5.4)(sass@1.79.5)(search-insights@2.17.2)(sortablejs@1.15.3)(terser@5.36.0)(typescript@5.6.3)
version: 1.4.5(@algolia/client-search@5.12.0)(@types/node@22.8.7)(async-validator@4.2.5)(axios@1.7.7)(change-case@5.4.4)(less@4.2.0)(nprogress@0.2.0)(postcss@8.4.47)(qrcode@1.5.4)(sass@1.80.6)(search-insights@2.17.2)(sortablejs@1.15.3)(terser@5.36.0)(typescript@5.6.3)
vue:
specifier: ^3.5.12
version: 3.5.12(typescript@5.6.3)
@ -933,7 +939,7 @@ importers:
version: 4.1.4(@typescript-eslint/eslint-plugin@8.12.2(@typescript-eslint/parser@8.12.2(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint@9.14.0(jiti@2.4.0))
eslint-plugin-vitest:
specifier: 'catalog:'
version: 0.5.4(@typescript-eslint/eslint-plugin@8.12.2(@typescript-eslint/parser@8.12.2(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3)(vitest@2.1.4(@types/node@22.8.7)(happy-dom@15.8.3)(less@4.2.0)(sass@1.79.5)(terser@5.36.0))
version: 0.5.4(@typescript-eslint/eslint-plugin@8.12.2(@typescript-eslint/parser@8.12.2(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3)(vitest@2.1.4(@types/node@22.8.7)(happy-dom@15.8.3)(less@4.2.0)(sass@1.80.6)(terser@5.36.0))
eslint-plugin-vue:
specifier: 'catalog:'
version: 9.30.0(eslint@9.14.0(jiti@2.4.0))
@ -1091,7 +1097,7 @@ importers:
version: link:../../packages/types
vite:
specifier: 'catalog:'
version: 5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.79.5)(terser@5.36.0)
version: 5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.80.6)(terser@5.36.0)
internal/vite-config:
dependencies:
@ -8913,6 +8919,11 @@ packages:
engines: {node: '>=14.0.0'}
hasBin: true
sass@1.80.6:
resolution: {integrity: sha512-ccZgdHNiBF1NHBsWvacvT5rju3y1d/Eu+8Ex6c21nHp2lZGLBEtuwc415QfiI1PJa1TpCo3iXwwSRjRpn2Ckjg==}
engines: {node: '>=14.0.0'}
hasBin: true
sax@1.4.1:
resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==}
@ -12451,11 +12462,11 @@ snapshots:
'@nodelib/fs.scandir': 2.1.5
fastq: 1.17.1
'@nolebase/ui@2.8.1(@algolia/client-search@5.12.0)(@types/node@22.8.7)(async-validator@4.2.5)(axios@1.7.7)(change-case@5.4.4)(nprogress@0.2.0)(postcss@8.4.47)(qrcode@1.5.4)(sass@1.79.5)(search-insights@2.17.2)(sortablejs@1.15.3)(terser@5.36.0)(typescript@5.6.3)':
'@nolebase/ui@2.8.1(@algolia/client-search@5.12.0)(@types/node@22.8.7)(async-validator@4.2.5)(axios@1.7.7)(change-case@5.4.4)(nprogress@0.2.0)(postcss@8.4.47)(qrcode@1.5.4)(sass@1.80.6)(search-insights@2.17.2)(sortablejs@1.15.3)(terser@5.36.0)(typescript@5.6.3)':
dependencies:
'@iconify-json/octicon': 1.2.1
less: 4.2.0
vitepress: 1.4.5(@algolia/client-search@5.12.0)(@types/node@22.8.7)(async-validator@4.2.5)(axios@1.7.7)(change-case@5.4.4)(less@4.2.0)(nprogress@0.2.0)(postcss@8.4.47)(qrcode@1.5.4)(sass@1.79.5)(search-insights@2.17.2)(sortablejs@1.15.3)(terser@5.36.0)(typescript@5.6.3)
vitepress: 1.4.5(@algolia/client-search@5.12.0)(@types/node@22.8.7)(async-validator@4.2.5)(axios@1.7.7)(change-case@5.4.4)(less@4.2.0)(nprogress@0.2.0)(postcss@8.4.47)(qrcode@1.5.4)(sass@1.80.6)(search-insights@2.17.2)(sortablejs@1.15.3)(terser@5.36.0)(typescript@5.6.3)
vue: 3.5.12(typescript@5.6.3)
transitivePeerDependencies:
- '@algolia/client-search'
@ -12486,10 +12497,10 @@ snapshots:
- typescript
- universal-cookie
'@nolebase/vitepress-plugin-git-changelog@2.8.1(@algolia/client-search@5.12.0)(@types/node@22.8.7)(async-validator@4.2.5)(axios@1.7.7)(change-case@5.4.4)(nprogress@0.2.0)(postcss@8.4.47)(qrcode@1.5.4)(sass@1.79.5)(search-insights@2.17.2)(sortablejs@1.15.3)(terser@5.36.0)(typescript@5.6.3)':
'@nolebase/vitepress-plugin-git-changelog@2.8.1(@algolia/client-search@5.12.0)(@types/node@22.8.7)(async-validator@4.2.5)(axios@1.7.7)(change-case@5.4.4)(nprogress@0.2.0)(postcss@8.4.47)(qrcode@1.5.4)(sass@1.80.6)(search-insights@2.17.2)(sortablejs@1.15.3)(terser@5.36.0)(typescript@5.6.3)':
dependencies:
'@iconify-json/octicon': 1.2.1
'@nolebase/ui': 2.8.1(@algolia/client-search@5.12.0)(@types/node@22.8.7)(async-validator@4.2.5)(axios@1.7.7)(change-case@5.4.4)(nprogress@0.2.0)(postcss@8.4.47)(qrcode@1.5.4)(sass@1.79.5)(search-insights@2.17.2)(sortablejs@1.15.3)(terser@5.36.0)(typescript@5.6.3)
'@nolebase/ui': 2.8.1(@algolia/client-search@5.12.0)(@types/node@22.8.7)(async-validator@4.2.5)(axios@1.7.7)(change-case@5.4.4)(nprogress@0.2.0)(postcss@8.4.47)(qrcode@1.5.4)(sass@1.80.6)(search-insights@2.17.2)(sortablejs@1.15.3)(terser@5.36.0)(typescript@5.6.3)
colorette: 2.0.20
date-fns: 4.1.0
defu: 6.1.4
@ -12499,7 +12510,7 @@ snapshots:
gray-matter: 4.0.3
less: 4.2.0
uncrypto: 0.1.3
vitepress: 1.4.5(@algolia/client-search@5.12.0)(@types/node@22.8.7)(async-validator@4.2.5)(axios@1.7.7)(change-case@5.4.4)(less@4.2.0)(nprogress@0.2.0)(postcss@8.4.47)(qrcode@1.5.4)(sass@1.79.5)(search-insights@2.17.2)(sortablejs@1.15.3)(terser@5.36.0)(typescript@5.6.3)
vitepress: 1.4.5(@algolia/client-search@5.12.0)(@types/node@22.8.7)(async-validator@4.2.5)(axios@1.7.7)(change-case@5.4.4)(less@4.2.0)(nprogress@0.2.0)(postcss@8.4.47)(qrcode@1.5.4)(sass@1.80.6)(search-insights@2.17.2)(sortablejs@1.15.3)(terser@5.36.0)(typescript@5.6.3)
transitivePeerDependencies:
- '@algolia/client-search'
- '@types/node'
@ -13354,9 +13365,9 @@ snapshots:
- encoding
- supports-color
'@vite-pwa/vitepress@0.5.3(vite-plugin-pwa@0.20.5(vite@5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.79.5)(terser@5.36.0))(workbox-build@7.3.0)(workbox-window@7.3.0))':
'@vite-pwa/vitepress@0.5.3(vite-plugin-pwa@0.20.5(vite@5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.80.6)(terser@5.36.0))(workbox-build@7.3.0)(workbox-window@7.3.0))':
dependencies:
vite-plugin-pwa: 0.20.5(vite@5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.79.5)(terser@5.36.0))(workbox-build@7.3.0)(workbox-window@7.3.0)
vite-plugin-pwa: 0.20.5(vite@5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.80.6)(terser@5.36.0))(workbox-build@7.3.0)(workbox-window@7.3.0)
'@vitejs/plugin-vue-jsx@4.0.1(vite@5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.79.5)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3))':
dependencies:
@ -13368,11 +13379,26 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@vitejs/plugin-vue-jsx@4.0.1(vite@5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.80.6)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3))':
dependencies:
'@babel/core': 7.26.0
'@babel/plugin-transform-typescript': 7.25.9(@babel/core@7.26.0)
'@vue/babel-plugin-jsx': 1.2.5(@babel/core@7.26.0)
vite: 5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.80.6)(terser@5.36.0)
vue: 3.5.12(typescript@5.6.3)
transitivePeerDependencies:
- supports-color
'@vitejs/plugin-vue@5.1.4(vite@5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.79.5)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3))':
dependencies:
vite: 5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.79.5)(terser@5.36.0)
vue: 3.5.12(typescript@5.6.3)
'@vitejs/plugin-vue@5.1.4(vite@5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.80.6)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3))':
dependencies:
vite: 5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.80.6)(terser@5.36.0)
vue: 3.5.12(typescript@5.6.3)
'@vitest/expect@2.1.4':
dependencies:
'@vitest/spy': 2.1.4
@ -13380,13 +13406,13 @@ snapshots:
chai: 5.1.2
tinyrainbow: 1.2.0
'@vitest/mocker@2.1.4(vite@5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.79.5)(terser@5.36.0))':
'@vitest/mocker@2.1.4(vite@5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.80.6)(terser@5.36.0))':
dependencies:
'@vitest/spy': 2.1.4
estree-walker: 3.0.3
magic-string: 0.30.12
optionalDependencies:
vite: 5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.79.5)(terser@5.36.0)
vite: 5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.80.6)(terser@5.36.0)
'@vitest/pretty-format@2.1.4':
dependencies:
@ -15291,13 +15317,13 @@ snapshots:
optionalDependencies:
'@typescript-eslint/eslint-plugin': 8.12.2(@typescript-eslint/parser@8.12.2(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3)
eslint-plugin-vitest@0.5.4(@typescript-eslint/eslint-plugin@8.12.2(@typescript-eslint/parser@8.12.2(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3)(vitest@2.1.4(@types/node@22.8.7)(happy-dom@15.8.3)(less@4.2.0)(sass@1.79.5)(terser@5.36.0)):
eslint-plugin-vitest@0.5.4(@typescript-eslint/eslint-plugin@8.12.2(@typescript-eslint/parser@8.12.2(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3)(vitest@2.1.4(@types/node@22.8.7)(happy-dom@15.8.3)(less@4.2.0)(sass@1.80.6)(terser@5.36.0)):
dependencies:
'@typescript-eslint/utils': 7.18.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3)
eslint: 9.14.0(jiti@2.4.0)
optionalDependencies:
'@typescript-eslint/eslint-plugin': 8.12.2(@typescript-eslint/parser@8.12.2(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3)
vitest: 2.1.4(@types/node@22.8.7)(happy-dom@15.8.3)(less@4.2.0)(sass@1.79.5)(terser@5.36.0)
vitest: 2.1.4(@types/node@22.8.7)(happy-dom@15.8.3)(less@4.2.0)(sass@1.80.6)(terser@5.36.0)
transitivePeerDependencies:
- supports-color
- typescript
@ -16777,7 +16803,7 @@ snapshots:
mkdirp@1.0.4: {}
mkdist@1.6.0(sass@1.79.5)(typescript@5.6.3)(vue-tsc@2.1.10(typescript@5.6.3)):
mkdist@1.6.0(sass@1.80.6)(typescript@5.6.3)(vue-tsc@2.1.10(typescript@5.6.3)):
dependencies:
autoprefixer: 10.4.20(postcss@8.4.47)
citty: 0.1.6
@ -16793,7 +16819,7 @@ snapshots:
semver: 7.6.3
tinyglobby: 0.2.10
optionalDependencies:
sass: 1.79.5
sass: 1.80.6
typescript: 5.6.3
vue-tsc: 2.1.10(typescript@5.6.3)
@ -18199,6 +18225,14 @@ snapshots:
immutable: 4.3.7
source-map-js: 1.2.1
sass@1.80.6:
dependencies:
chokidar: 4.0.1
immutable: 4.3.7
source-map-js: 1.2.1
optionalDependencies:
'@parcel/watcher': 2.4.1
sax@1.4.1:
optional: true
@ -18971,7 +19005,7 @@ snapshots:
has-symbols: 1.0.3
which-boxed-primitive: 1.0.2
unbuild@3.0.0-rc.11(sass@1.79.5)(typescript@5.6.3)(vue-tsc@2.1.10(typescript@5.6.3)):
unbuild@3.0.0-rc.11(sass@1.80.6)(typescript@5.6.3)(vue-tsc@2.1.10(typescript@5.6.3)):
dependencies:
'@rollup/plugin-alias': 5.1.1(rollup@4.24.3)
'@rollup/plugin-commonjs': 28.0.1(rollup@4.24.3)
@ -18986,7 +19020,7 @@ snapshots:
hookable: 5.5.3
jiti: 2.4.0
magic-string: 0.30.12
mkdist: 1.6.0(sass@1.79.5)(typescript@5.6.3)(vue-tsc@2.1.10(typescript@5.6.3))
mkdist: 1.6.0(sass@1.80.6)(typescript@5.6.3)(vue-tsc@2.1.10(typescript@5.6.3))
mlly: 1.7.2
pathe: 1.1.2
pkg-types: 1.2.1
@ -19241,12 +19275,12 @@ snapshots:
dependencies:
vite: 5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.79.5)(terser@5.36.0)
vite-node@2.1.4(@types/node@22.8.7)(less@4.2.0)(sass@1.79.5)(terser@5.36.0):
vite-node@2.1.4(@types/node@22.8.7)(less@4.2.0)(sass@1.80.6)(terser@5.36.0):
dependencies:
cac: 6.7.14
debug: 4.3.7(supports-color@9.4.0)
pathe: 1.1.2
vite: 5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.79.5)(terser@5.36.0)
vite: 5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.80.6)(terser@5.36.0)
transitivePeerDependencies:
- '@types/node'
- less
@ -19336,6 +19370,17 @@ snapshots:
transitivePeerDependencies:
- supports-color
vite-plugin-pwa@0.20.5(vite@5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.80.6)(terser@5.36.0))(workbox-build@7.3.0)(workbox-window@7.3.0):
dependencies:
debug: 4.3.7(supports-color@9.4.0)
pretty-bytes: 6.1.1
tinyglobby: 0.2.10
vite: 5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.80.6)(terser@5.36.0)
workbox-build: 7.3.0
workbox-window: 7.3.0
transitivePeerDependencies:
- supports-color
vite-plugin-vue-devtools@7.6.2(rollup@4.24.4)(vite@5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.79.5)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)):
dependencies:
'@vue/devtools-core': 7.6.2(vite@5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.79.5)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3))
@ -19379,6 +19424,18 @@ snapshots:
sass: 1.79.5
terser: 5.36.0
vite@5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.80.6)(terser@5.36.0):
dependencies:
esbuild: 0.21.5
postcss: 8.4.47
rollup: 4.24.3
optionalDependencies:
'@types/node': 22.8.7
fsevents: 2.3.3
less: 4.2.0
sass: 1.80.6
terser: 5.36.0
vitepress-plugin-group-icons@1.3.0:
dependencies:
'@iconify-json/logos': 1.2.3
@ -19387,7 +19444,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
vitepress@1.4.5(@algolia/client-search@5.12.0)(@types/node@22.8.7)(async-validator@4.2.5)(axios@1.7.7)(change-case@5.4.4)(less@4.2.0)(nprogress@0.2.0)(postcss@8.4.47)(qrcode@1.5.4)(sass@1.79.5)(search-insights@2.17.2)(sortablejs@1.15.3)(terser@5.36.0)(typescript@5.6.3):
vitepress@1.4.5(@algolia/client-search@5.12.0)(@types/node@22.8.7)(async-validator@4.2.5)(axios@1.7.7)(change-case@5.4.4)(less@4.2.0)(nprogress@0.2.0)(postcss@8.4.47)(qrcode@1.5.4)(sass@1.80.6)(search-insights@2.17.2)(sortablejs@1.15.3)(terser@5.36.0)(typescript@5.6.3):
dependencies:
'@docsearch/css': 3.6.3
'@docsearch/js': 3.6.3(@algolia/client-search@5.12.0)(search-insights@2.17.2)
@ -19395,7 +19452,7 @@ snapshots:
'@shikijs/transformers': 1.22.2
'@shikijs/types': 1.22.2
'@types/markdown-it': 14.1.2
'@vitejs/plugin-vue': 5.1.4(vite@5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.79.5)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3))
'@vitejs/plugin-vue': 5.1.4(vite@5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.80.6)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3))
'@vue/devtools-api': 7.6.2
'@vue/shared': 3.5.12
'@vueuse/core': 11.2.0(vue@3.5.12(typescript@5.6.3))
@ -19404,7 +19461,7 @@ snapshots:
mark.js: 8.11.1
minisearch: 7.1.0
shiki: 1.22.2
vite: 5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.79.5)(terser@5.36.0)
vite: 5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.80.6)(terser@5.36.0)
vue: 3.5.12(typescript@5.6.3)
optionalDependencies:
postcss: 8.4.47
@ -19436,10 +19493,10 @@ snapshots:
- typescript
- universal-cookie
vitest@2.1.4(@types/node@22.8.7)(happy-dom@15.8.3)(less@4.2.0)(sass@1.79.5)(terser@5.36.0):
vitest@2.1.4(@types/node@22.8.7)(happy-dom@15.8.3)(less@4.2.0)(sass@1.80.6)(terser@5.36.0):
dependencies:
'@vitest/expect': 2.1.4
'@vitest/mocker': 2.1.4(vite@5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.79.5)(terser@5.36.0))
'@vitest/mocker': 2.1.4(vite@5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.80.6)(terser@5.36.0))
'@vitest/pretty-format': 2.1.4
'@vitest/runner': 2.1.4
'@vitest/snapshot': 2.1.4
@ -19455,8 +19512,8 @@ snapshots:
tinyexec: 0.3.1
tinypool: 1.0.1
tinyrainbow: 1.2.0
vite: 5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.79.5)(terser@5.36.0)
vite-node: 2.1.4(@types/node@22.8.7)(less@4.2.0)(sass@1.79.5)(terser@5.36.0)
vite: 5.4.10(@types/node@22.8.7)(less@4.2.0)(sass@1.80.6)(terser@5.36.0)
vite-node: 2.1.4(@types/node@22.8.7)(less@4.2.0)(sass@1.80.6)(terser@5.36.0)
why-is-node-running: 2.3.0
optionalDependencies:
'@types/node': 22.8.7