This commit is contained in:
dap
2024-10-05 00:30:29 +08:00
118 changed files with 2479 additions and 125 deletions

View File

@@ -12,5 +12,5 @@ function handleClick() {
</script>
<template>
<Button type="link" @click="handleClick">查看组件文档</Button>
<Button @click="handleClick">查看组件文档</Button>
</template>

View File

@@ -6,6 +6,8 @@ import dayjs from 'dayjs';
import { useVbenForm } from '#/adapter';
import DocButton from '../doc-button.vue';
const [BaseForm, baseFormApi] = useVbenForm({
// 所有表单项共用,可单独在表单内覆盖
commonConfig: {
@@ -329,6 +331,9 @@ function handleSetFormValue() {
description="表单组件基础示例,请注意,该页面用到的参数代码会添加一些简单注释,方便理解,请仔细查看。"
title="表单组件"
>
<template #extra>
<DocButton path="/components/common-ui/vben-form" />
</template>
<Card title="基础示例">
<template #extra>
<Button type="primary" @click="handleSetFormValue">设置表单值</Button>

View File

@@ -0,0 +1,93 @@
<script lang="ts" setup>
import type { VxeGridListeners, VxeGridProps } from '#/adapter';
import { Page } from '@vben/common-ui';
import { Button, message } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter';
import DocButton from '../doc-button.vue';
import { MOCK_TABLE_DATA } from './table-data';
interface RowType {
address: string;
age: number;
id: number;
name: string;
nickname: string;
role: string;
}
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,
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>
<Page
description="表格组件常用于快速开发数据展示与交互界面示例数据为静态数据。该组件是对vxe-table进行简单的二次封装大部分属性与方法与vxe-table保持一致。"
title="表格基础示例"
>
<template #extra>
<DocButton path="/components/common-ui/vben-vxe-table" />
</template>
<Grid>
<template #toolbar-actions>
<Button class="mr-2" type="primary">左右按钮插槽</Button>
</template>
<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>
</Page>
</template>

View File

@@ -0,0 +1,110 @@
<script lang="ts" setup>
import type { VxeGridProps } from '#/adapter';
import { Page } from '@vben/common-ui';
import { Button, Image, Switch, Tag } from 'ant-design-vue';
import dayjs from 'dayjs';
import { useVbenVxeGrid } from '#/adapter';
import { getExampleTableApi } from '#/api';
interface RowType {
category: string;
color: string;
id: string;
imageUrl: string;
open: boolean;
price: string;
productName: string;
releaseDate: string;
status: 'error' | 'success' | 'warning';
}
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: ({ cellValue }) => {
return dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss');
},
title: 'Date',
width: 200,
},
{
cellRender: { name: 'CellLink', props: { text: '编辑' } },
field: 'action',
fixed: 'right',
title: '操作',
width: 120,
},
],
height: 'auto',
keepSource: true,
pagerConfig: {},
proxyConfig: {
ajax: {
query: async ({ page }) => {
return await getExampleTableApi({
page: page.currentPage,
pageSize: page.pageSize,
});
},
},
},
};
const [Grid] = useVbenVxeGrid({ gridOptions });
</script>
<template>
<Page auto-content-height>
<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>
</Page>
</template>

View File

@@ -0,0 +1,57 @@
<script lang="ts" setup>
import type { VxeGridProps } from '#/adapter';
import { Page } from '@vben/common-ui';
import { useVbenVxeGrid } from '#/adapter';
import { getExampleTableApi } from '#/api';
interface RowType {
category: string;
color: string;
id: string;
price: string;
productName: string;
releaseDate: string;
}
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', title: 'Date' },
],
editConfig: {
mode: 'cell',
trigger: 'click',
},
height: 'auto',
pagerConfig: {},
proxyConfig: {
ajax: {
query: async ({ page }) => {
return await getExampleTableApi({
page: page.currentPage,
pageSize: page.pageSize,
});
},
},
},
showOverflow: true,
};
const [Grid] = useVbenVxeGrid({ gridOptions });
</script>
<template>
<Page auto-content-height>
<Grid />
</Page>
</template>

View File

@@ -0,0 +1,94 @@
<script lang="ts" setup>
import type { VxeGridProps } from '#/adapter';
import { Page } from '@vben/common-ui';
import { Button, message } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter';
import { getExampleTableApi } from '#/api';
interface RowType {
category: string;
color: string;
id: string;
price: string;
productName: string;
releaseDate: string;
}
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', title: 'Date' },
{ slots: { default: 'action' }, title: '操作' },
],
editConfig: {
mode: 'row',
trigger: 'click',
},
height: 'auto',
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>
<Page auto-content-height>
<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>
</Page>
</template>

View File

@@ -0,0 +1,64 @@
<script lang="ts" setup>
import type { VxeGridProps } from '#/adapter';
import { Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter';
import { getExampleTableApi } from '#/api';
interface RowType {
category: string;
color: string;
id: string;
price: string;
productName: string;
releaseDate: string;
}
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', title: 'Date', width: 500 },
{
field: 'action',
fixed: 'right',
slots: { default: 'action' },
title: '操作',
width: 120,
},
],
height: 'auto',
pagerConfig: {},
proxyConfig: {
ajax: {
query: async ({ page }) => {
return await getExampleTableApi({
page: page.currentPage,
pageSize: page.pageSize,
});
},
},
},
rowConfig: {
isHover: true,
},
};
const [Grid] = useVbenVxeGrid({ gridOptions });
</script>
<template>
<Page auto-content-height>
<Grid>
<template #action>
<Button type="link">编辑</Button>
</template>
</Grid>
</Page>
</template>

View File

@@ -0,0 +1,102 @@
<script lang="ts" setup>
import type { VbenFormProps, VxeGridProps } from '#/adapter';
import { Page } from '@vben/common-ui';
import { message } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter';
import { getExampleTableApi } from '#/api';
interface RowType {
category: string;
color: string;
id: string;
price: string;
productName: string;
releaseDate: string;
}
const formOptions: VbenFormProps = {
schema: [
{
component: 'Input',
fieldName: 'category',
label: 'Category',
},
{
component: 'Input',
fieldName: 'productName',
label: 'ProductName',
},
{
component: 'Input',
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',
},
],
};
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', title: 'Date' },
],
height: 'auto',
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>
<Page auto-content-height>
<Grid />
</Page>
</template>

View File

@@ -0,0 +1,65 @@
<script lang="ts" setup>
import type { VxeGridProps } from '#/adapter';
import { Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter';
import { getExampleTableApi } from '#/api';
interface RowType {
category: string;
color: string;
id: string;
price: string;
productName: string;
releaseDate: string;
}
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', title: 'Date' },
],
height: 'auto',
keepSource: true,
pagerConfig: {},
proxyConfig: {
ajax: {
query: async ({ page }) => {
return await getExampleTableApi({
page: page.currentPage,
pageSize: page.pageSize,
});
},
},
},
};
const [Grid, gridApi] = useVbenVxeGrid({ gridOptions });
</script>
<template>
<Page auto-content-height>
<Grid>
<template #toolbar-tools>
<Button class="mr-2" type="primary" @click="() => gridApi.query()">
刷新当前页面
</Button>
<Button type="primary" @click="() => gridApi.reload()">
刷新并返回第一页
</Button>
</template>
</Grid>
</Page>
</template>

View File

@@ -0,0 +1,172 @@
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 < 40; 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',
},
];

View File

@@ -0,0 +1,59 @@
<script lang="ts" setup>
import type { VxeGridProps } from '#/adapter';
import { Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter';
import { MOCK_TREE_TABLE_DATA } from './table-data';
interface RowType {
date: string;
id: number;
name: string;
parentId: null | number;
size: number;
type: string;
}
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,
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>
<Page>
<Grid>
<template #toolbar-tools>
<Button class="mr-2" type="primary" @click="expandAll">
展开全部
</Button>
<Button type="primary" @click="collapseAll"> 折叠全部 </Button>
</template>
</Grid>
</Page>
</template>

View File

@@ -0,0 +1,63 @@
<script lang="ts" setup>
import type { VxeGridProps } from '#/adapter';
import { onMounted } from 'vue';
import { Page } from '@vben/common-ui';
import { useVbenVxeGrid } from '#/adapter';
interface RowType {
id: number;
name: string;
role: string;
sex: string;
}
const gridOptions: VxeGridProps<RowType> = {
columns: [
{ type: 'seq', width: 70 },
{ field: 'name', title: 'Name' },
{ field: 'role', title: 'Role' },
{ field: 'sex', title: 'Sex' },
],
data: [],
height: 'auto',
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>
<Page auto-content-height>
<Grid />
</Page>
</template>