UI组件示例代码

pull/975/head
zhangdaiscott 2023-12-29 21:22:25 +08:00
parent 81579acf0e
commit 81381f3b64
45 changed files with 4811 additions and 0 deletions

View File

@ -0,0 +1,81 @@
<!-- 标题与字段布局 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" @submit="handleSubmit" style="margin: 20px auto"/>
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
//
const formSchemas: FormSchema[] = [
{
label: '姓名',
field: 'name',
component: 'Input',
},
{
label: '年龄',
field: 'password',
component: 'InputNumber',
},
{
label: '生日',
field: 'birthday',
component: 'DatePicker',
},
{
label: '头像',
field: 'avatar',
component: 'JImageUpload',
},
];
/**
* BasicForm绑定注册;
*/
const [registerForm] = useForm({
//
schemas: formSchemas,
showActionButtonGroup: false,
actionColOptions: { span: 12 },
//
labelCol: {
xs: 2,
sm: 2,
md: 2,
lg: 9,
xl: 3,
xxl: 2,
},
//
wrapperCol: {
xs: 15,
sm: 14,
md: 16,
lg: 17,
xl: 19,
xxl: 20,
},
});
/**
* 点击提交按钮的value值
* @param values
*/
function handleSubmit(values: any) {
console.log('提交按钮数据::::', values);
}
</script>
<style scoped>
/** 时间和数字输入框样式 */
:deep(.ant-input-number) {
width: 100%;
}
:deep(.ant-picker) {
width: 100%;
}
</style>

View File

@ -0,0 +1,70 @@
<!-- 固定label标题的宽度 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" @submit="handleSubmit" style="margin-top: 20px" />
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
//
const formSchemas: FormSchema[] = [
{
label: '姓名',
field: 'name',
component: 'Input',
},
{
label: '年龄',
field: 'password',
component: 'InputNumber',
},
{
label: '生日',
field: 'birthday',
component: 'DatePicker',
},
{
label: '头像',
field: 'avatar',
component: 'JImageUpload',
},
];
/**
* BasicForm绑定注册;
*/
const [registerForm] = useForm({
//
schemas: formSchemas,
showResetButton: false,
submitButtonOptions: { text: '提交', preIcon: '' },
actionColOptions: { span: 17 },
//使labelWidth
labelWidth: '150px',
//使labelCol
labelCol: { style: { width: '150px' } },
//left:right
labelAlign: 'right',
});
/**
* 点击提交按钮的value值
* @param values
*/
function handleSubmit(values: any) {
console.log('提交按钮数据::::', values);
}
</script>
<style scoped>
/** 时间和数字输入框样式 */
:deep(.ant-input-number) {
width: 100%;
}
:deep(.ant-picker) {
width: 100%;
}
</style>

View File

@ -0,0 +1,143 @@
<!-- 动态增减表单 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin-top: 20px;" @submit="handleSubmit">
<!-- 添加input的插槽 -->
<template #addForm="{ field }">
<a-button v-if="Number(field) === 0" @click="addField" style="width: 50px">+</a-button>
<a-button v-if="Number(field) > 0" @click="delField(field)" style="width: 50px">-</a-button>
</template>
</BasicForm>
<!-- <div style="margin: 20px auto; text-align: center">
<a-button @click="addField"></a-button>
</div>-->
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
import { CollapseContainer } from '/@/components/Container';
import { ref } from '@vue/runtime-core';
//
const formSchemas: FormSchema[] = [
{
field: 'name1',
label: '姓名1',
component: 'Input',
// ifShow:false,
colProps: {
span: 8,
},
},
{
field: 'age1',
label: '年龄1',
component: 'InputNumber',
// ifShow:false,
colProps: {
span: 8,
},
},
{
field: '0',
component: 'Input',
// ifShow:false,
label: ' ',
colProps: {
span: 8,
},
slot: 'addForm',
},
];
/**
* BasicForm绑定注册;
* appendSchemaByField:增加表单项字段
*
* removeSchemaByFiled:减少表单项字段
*/
const [registerForm, { appendSchemaByField, removeSchemaByFiled }] = useForm({
schemas: formSchemas,
showResetButton: false,
labelWidth: '150px',
// showSubmitButton:false
submitButtonOptions: { text: '提交', preIcon: '' },
actionColOptions: { span: 17 },
});
//
let n = ref<number>(2);
/**
* 添加字段
* appendSchemaByField类型: ( schema: FormSchema, prefixField: string | undefined, first?: boolean | undefined ) => Promise<void>
* 说明: 插入到指定 filed 后面如果没传指定 field则插入到最后, first = true 时插入到第一个位置
*/
async function addField() {
//schemas
await appendSchemaByField(
{
field: `name${n.value}`,
component: 'Input',
label: '字段' + n.value,
colProps: {
span: 8,
},
},
''
);
await appendSchemaByField(
{
field: `sex${n.value}`,
component: 'InputNumber',
label: '字段' + n.value,
colProps: {
span: 8,
},
},
''
);
await appendSchemaByField(
{
field: `${n.value}`,
component: 'Input',
label: ' ',
colProps: {
span: 8,
},
slot: 'addForm',
},
''
);
n.value++;
}
/**
* 删除字段
* 类型: (field: string | string[]) => Promise<void>
* 说明: 根据 field 删除 Schema
* @param field 当前字段名称
*/
function delField(field) {
//
removeSchemaByFiled([`name${field}`, `sex${field}`, `${field}`]);
n.value--;
}
/**
* 点击提交按钮的value值
* @param values
*/
function handleSubmit(values: any) {
console.log('提交按钮数据::::', values);
}
</script>
<style scoped>
/** 数字输入框样式 */
:deep(.ant-input-number) {
width: 100%;
}
</style>

View File

@ -0,0 +1,66 @@
<!-- 操作按钮 -->
<template>
<div style="margin: 20px auto; text-align: center">
<!-- 通过setProps 可以设置 userForm 中的属性 -->
<!-- showActionButtonGroup 显示或者隐藏查询重置按钮 -->
<a-button @click="setProps({ showActionButtonGroup: false })" class="mr-2"> 隐藏操作按钮 </a-button>
<a-button @click="setProps({ showActionButtonGroup: true })" class="mr-2"> 显示操作按钮 </a-button>
<!-- showActionButtonGroup 显示或者隐藏重置按钮 -->
<a-button @click="setProps({ showResetButton: false })" class="mr-2"> 隐藏重置按钮 </a-button>
<a-button @click="setProps({ showResetButton: true })" class="mr-2"> 显示重置按钮 </a-button>
<!-- showActionButtonGroup 显示或者隐藏查询按钮 -->
<a-button @click="setProps({ showSubmitButton: false })" class="mr-2"> 隐藏查询按钮 </a-button>
<a-button @click="setProps({ showSubmitButton: true })" class="mr-2"> 显示查询按钮 </a-button>
</div>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" @submit="handleSubmit" style="margin-top: 50px; margin-left: 50px" />
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
import { CollapseContainer } from '/@/components/Container';
/**
* BasicForm绑定注册;
* setProps方法可以动态设置useForm中的属性
*/
const [registerForm, { setProps }] = useForm({
//
submitButtonOptions: { text: '查询', preIcon: '' },
//
resetButtonOptions: { text: '重置', preIcon: '' },
//
actionColOptions: { span: 17 },
//
submitFunc: customSubmitFunc,
//
resetFunc: customSubmitFunc,
//
showActionButtonGroup: true,
});
/**
* 查询按钮点击事件
*/
async function customSubmitFunc() {
console.log('查询按钮点击事件,此处处理查询按钮的逻辑');
}
/**
* 重置按钮点击事件
*/
async function customResetFunc() {
console.log('重置按钮点击事件,此处处理重置按钮的逻辑');
}
/**
* 点击提交按钮的value值
* @param values
*/
function handleSubmit(values: any) {
console.log('提交按钮数据::::', values);
}
</script>
<style scoped></style>

View File

@ -0,0 +1,95 @@
<!-- 操作禁用表单 -->
<template>
<div style="margin: 20px auto; text-align: center">
<!-- all 触发或清空所有验证visitor 只触发或者清空来访人员验证 -->
<a-button @click="triggerFormRule('all')" class="mr-2"> 触发表单验证 </a-button>
<a-button @click="cancelFormRule('all')" class="mr-2"> 清空表单验证 </a-button>
<a-button @click="triggerFormRule('visitor')" class="mr-2"> 只验证来访人员 </a-button>
<a-button @click="cancelFormRule('visitor')" class="mr-2"> 只清空来访人员验证 </a-button>
</div>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin-top: 20px;" />
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
//
const formSchemas: FormSchema[] = [
{
field: 'visitor',
label: '来访人员',
component: 'Input',
required: true,
},
{
field: 'accessed',
label: '来访日期',
component: 'DatePicker',
required: true,
},
{
field: 'phone',
label: '来访人手机号',
component: 'Input',
required: true,
},
];
/**
* BasicForm绑定注册;
* clearValidate 清除所有验证支持取消验证其中几个字段 clearValidate(['visitor',...])
* validate 验证所有,支持验证其中几个字段validate(['visitor',...])
* validateFields 只支持验证其中几个字段如validateFields(['visitor',...])
*/
const [registerForm, { clearValidate, validateFields, validate }] = useForm({
schemas: formSchemas,
labelWidth: '150px',
//
showActionButtonGroup: false,
//input
autoFocusFirstItem: true,
});
/**
* 触发表单验证
* @param type all 所有验证 visitor 只验证来访人员
*/
async function triggerFormRule(type) {
if (type == 'all') {
//
await validate();
} else {
//访
//visitor 访formSchemas field
await validateFields(['visitor']);
}
}
/**
* 触发表单验证
* @param type all 所有验证 visitor 只验证来访人员
*/
async function cancelFormRule(type) {
if (type == 'all') {
//
await clearValidate();
} else {
//访
//visitor 访formSchemas field
await clearValidate(['visitor']);
}
}
</script>
<style scoped>
/** 时间和数字输入框样式 */
:deep(.ant-input-number) {
width: 100%;
}
:deep(.ant-picker) {
width: 100%;
}
</style>

View File

@ -0,0 +1,58 @@
<!-- 操作禁用表单 -->
<template>
<div style="margin: 20px auto; text-align: center">
<!-- 通过setProps 可以设置 userForm 中的属性 -->
<!-- 表单大小默认为 default -->
<a-button @click="setProps({ size: 'large' })" class="mr-2"> 更改大小为最大 </a-button>
<a-button @click="setProps({ size: 'default' })" class="mr-2"> 还原大小 </a-button>
<a-button @click="setProps({ size: 'small' })" class="mr-2"> 更改大小为最小 </a-button>
<!-- disabled表单禁用 -->
<a-button @click="setProps({ disabled: true })" class="mr-2"> 禁用表单 </a-button>
<a-button @click="setProps({ disabled: false })" class="mr-2"> 解除禁用 </a-button>
<!-- compact 是否为紧凑表单 -->
<a-button @click="setProps({ compact: true })" class="mr-2"> 紧凑表单 </a-button>
<a-button @click="setProps({ compact: false })" class="mr-2"> 还原正常间距 </a-button>
</div>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin-top: 20px;" />
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
import { CollapseContainer } from '/@/components/Container';
//
const formSchemas: FormSchema[] = [
{
field: 'visitor',
label: '来访人员',
component: 'Input',
},
{
field: 'accessed',
label: '来访日期',
component: 'DatePicker',
},
{
field: 'phone',
label: '来访人手机号',
component: 'Input',
},
];
/**
* BasicForm绑定注册;
* setProps方法可以动态设置useForm中的属性
*/
const [registerForm, { setProps }] = useForm({
schemas: formSchemas,
labelWidth: '150px',
//
showActionButtonGroup: false,
//input
autoFocusFirstItem: true,
});
</script>
<style scoped></style>

View File

@ -0,0 +1,34 @@
<!-- 操作表单值 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin-top: 20px;" />
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
import { schemas } from './example.data';
/**
* BasicForm绑定注册;
*/
const [registerForm, { getFieldsValue, setFieldsValue, resetFields, validate }] = useForm({
schemas: schemas,
labelWidth: '150px',
//
showActionButtonGroup: false,
//input
autoFocusFirstItem: true,
});
</script>
<style scoped>
/** 时间和数字输入框样式 */
:deep(.ant-input-number) {
width: 100%;
}
:deep(.ant-picker) {
width: 100%;
}
</style>

View File

@ -0,0 +1,63 @@
<!-- 控件属性 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin-top: 20px" />
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
//
const formSchemas: FormSchema[] = [
{
label: '员工姓名',
field: 'name',
component: 'Input',
componentProps: {
disabled: true,
},
defaultValue: '张三',
},
{
label: '性别',
field: 'sex',
component: 'Select',
//
componentProps: {
options: [
{ label: '男', value: 1 },
{ label: '女', value: 2 },
{ label: '未知', value: 3 },
],
},
//
defaultValue: 3,
},
{
label: '年龄',
field: 'age',
component: 'Input',
},
{
label: '入职时间',
subLabel: '( 选填 )',
field: 'entryTime',
component: 'TimePicker',
},
];
/**
* BasicForm绑定注册;
*/
const [registerForm] = useForm({
//
schemas: formSchemas,
labelWidth: '150px',
showResetButton: false,
submitButtonOptions: { text: '提交', preIcon: '' },
actionColOptions: { span: 17 },
});
</script>
<style scoped></style>

View File

@ -0,0 +1,32 @@
<!-- 自定义组件 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin-top: 20px" />
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
//
const formSchemas: FormSchema[] = [
{
field: 'custom',
label: '自定义组件',
//
component: 'JInput',
},
];
/**
* BasicForm绑定注册;
*/
const [registerForm] = useForm({
//
schemas: formSchemas,
labelWidth: '150px',
showActionButtonGroup: false,
});
</script>
<style scoped></style>

View File

@ -0,0 +1,32 @@
<!-- 操作表单值 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin-top: 20px" />
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
import { schemas } from './exampleCustom.data';
/**
* BasicForm绑定注册;
*/
const [registerForm, { getFieldsValue, setFieldsValue, resetFields, validate }] = useForm({
schemas: schemas,
labelWidth: '150px',
//
showActionButtonGroup: false,
});
</script>
<style scoped>
/** 时间和数字输入框样式 */
:deep(.ant-input-number) {
width: 100%;
}
:deep(.ant-picker) {
width: 100%;
}
</style>

View File

@ -0,0 +1,64 @@
<!-- 插槽 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin-top: 20px" @submit="handleSubmit">
<!-- #name对应的是formSchemas对应slot(name)插槽 -->
<template #name="{ model, field }">
<JInput v-model:value="model[field]" />
</template>
</BasicForm>
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
//CustomDemo
import JInput from "/@/components/Form/src/jeecg/components/JInput.vue";
//
const formSchemas: FormSchema[] = [
{
field: 'name',
label: '姓名',
component: 'Input',
slot:'name'
},
{
field: 'phone',
label: '联系方式',
component: 'Input',
},
{
field: 'feedback',
label: '问题反馈',
component: 'InputTextArea',
},
];
/**
* BasicForm绑定注册;
*/
const [registerForm] = useForm({
//
schemas: formSchemas,
showResetButton: false,
labelWidth: '150px',
submitButtonOptions: { text: '提交', preIcon: '' },
actionColOptions: { span: 17 },
});
/**
* 提交信息
*/
function handleSubmit(values) {
console.log("values::",values);
}
</script>
<style scoped>
.font-color {
font-size: 13px;
color: #a1a1a1;
margin-bottom: 5px;
}
</style>

View File

@ -0,0 +1,80 @@
<!-- 动态表单验证 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin-top: 20px" @submit="handleSubmit" />
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
import { duplicateCheck } from '/@/views/system/user/user.api';
//
const formSchemas: FormSchema[] = [
{
field: 'visitor',
label: '来访人员',
component: 'Input',
//
required: true,
},
{
field: 'accessed',
label: '来访日期',
component: 'DatePicker',
// values
required: ({ values }) => {
return !values.accessed;
},
},
{
field: 'phone',
label: '来访人手机号',
component: 'Input',
//values:
dynamicRules: ({ values }) => {
//return
return [
{
//
required: true,
// value
validator: (_, value) => {
//return Promise
return new Promise((resolve, reject) => {
if (!value) {
reject('请输入手机号!');
}
//
let reg = /^1[3456789]\d{9}$/;
if (!reg.test(value)) {
reject('请输入正确手机号!');
}
resolve();
});
},
},
];
},
},
];
/**
* BasicForm绑定注册;
*/
const [registerForm] = useForm({
//
schemas: formSchemas,
showResetButton: false,
labelWidth: '150px',
submitButtonOptions: { text: '提交', preIcon: '' },
actionColOptions: { span: 17 },
});
/**
* 提交事件
*/
function handleSubmit(values: any) {}
</script>
<style scoped></style>

View File

@ -0,0 +1,70 @@
<!-- 字段显示与隐藏 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin-top: 20px" />
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
//
const formSchemas: FormSchema[] = [
{
field: 'id',
label: '编号',
component: 'Input',
//idcss dom truefalseifShow
show: false,
},
{
field: 'evaluate',
label: '对公司整体评价',
component: 'RadioGroup',
componentProps: {
options: [
{ label: '满意', value: '0' },
{ label: '不满意', value: '1' },
],
},
defaultValue: '0',
},
{
field: 'describe',
label: '不满意原因说明',
component: 'InputTextArea',
//ifShowshow使valuesjs dom
ifShow: ({ values }) => {
return values.evaluate == '1';
},
},
{
field: 'satisfiedLevel',
label: '满意度',
component: 'Slider',
componentProps: {
tipFormatter: (value) => {
return value + '%';
},
},
//values truefalse
dynamicDisabled: ({ values }) => {
return values.evaluate == '1';
},
},
];
/**
* BasicForm绑定注册;
*/
const [registerForm] = useForm({
//
schemas: formSchemas,
showResetButton: false,
labelWidth: '150px',
submitButtonOptions: { text: '提交', preIcon: '' },
actionColOptions: { span: 17 },
});
</script>
<style scoped></style>

View File

@ -0,0 +1,55 @@
<!-- 字段标题提示及前缀 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin-top: 20px" />
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
//
const formSchemas: FormSchema[] = [
{
field: 'month',
label: '当前月份',
component: 'Input',
suffix: '月',
},
{
field: 'lateNumber',
label: '迟到次数',
component: 'InputNumber',
//String(helpMessage:"")
helpMessage: ({ values }) => {
return '当前迟到次数' + values.lateNumber + ', 扣款' + values.lateNumber * 50 + '元';
},
defaultValue: 0,
},
{
field: 'lateReason',
label: '迟到原因',
component: 'Input',
helpMessage: '什么原因耽误上班迟到',
//helpMessage使
helpComponentProps: {
maxWidth: '200px',
color: '#66CCFF',
},
},
];
/**
* BasicForm绑定注册;
*/
const [registerForm] = useForm({
//
schemas: formSchemas,
showResetButton: false,
labelWidth: '150px',
submitButtonOptions: { text: '提交', preIcon: '' },
actionColOptions: { span: 17 },
});
</script>
<style scoped></style>

View File

@ -0,0 +1,105 @@
<!-- 自定义页脚 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin-top: 20px">
<template #formHeader>
<div style="margin: 0 auto 20px">
<span>我是自定义按钮</span>
</div>
</template>
<template #formFooter>
<div style="margin: 0 auto">
<a-button type="primary" @click="save" class="mr-2"> 保存 </a-button>
<a-button type="primary" @click="saveDraft" class="mr-2"> 保存草稿 </a-button>
<a-button type="error" @click="reset" class="mr-2"> 重置 </a-button>
</div>
</template>
</BasicForm>
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
//
const formSchemas: FormSchema[] = [
{
label: '员工姓名',
field: 'name',
component: 'Input',
},
{
label: '性别',
field: 'sex',
component: 'Select',
//
componentProps: {
options: [
{ label: '男', value: 1 },
{ label: '女', value: 2 },
{ label: '未知', value: 3 },
],
},
//
defaultValue: 3,
},
{
label: '年龄',
field: 'age',
component: 'Input',
},
{
label: '入职时间',
subLabel: '( 选填 )',
field: 'entryTime',
component: 'TimePicker',
},
];
/**
* BasicForm绑定注册;
*/
const [registerForm, { validate, resetFields }] = useForm({
schemas: formSchemas,
labelWidth: '150px',
//
showActionButtonGroup: false,
});
/**
* 保存
*/
async function save() {
//使useForm
let values = await validate();
console.log(values);
}
/**
* 保存草稿
*/
async function saveDraft() {
//使useFormvalidate
let values = await validate();
console.log(values);
}
/**
* 重置
*/
async function reset() {
//使useFormresetFields
await resetFields();
}
</script>
<style scoped>
/** 时间和数字输入框样式 */
:deep(.ant-input-number) {
width: 100%;
}
:deep(.ant-picker) {
width: 100%;
}
</style>

View File

@ -0,0 +1,63 @@
<!-- 表单布局 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin-top: 20px" />
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
//
const formSchemas: FormSchema[] = [
{
label: '会议名称',
field: 'name',
component: 'Input',
},
{
label: '参会地点',
field: 'meetingLocation',
component: 'Input',
},
{
label: '参与人数',
field: 'numberOfPart',
component: 'InputNumber',
},
{
label: '会议纪要',
field: 'meetingMinutes',
component: 'JUpload',
},
];
/**
* BasicForm绑定注册;
*/
const [registerForm] = useForm({
//vertical,inlineinline
layout: 'inline',
//
schemas: formSchemas,
//
showActionButtonGroup: false,
//row, layout inline
rowProps: { gutter: 24, justify: 'center', align: 'middle' },
//col()schemascolProps
baseColProps: { span: 12 },
//row
baseRowStyle: { width: '100%' },
});
</script>
<style scoped>
/** 时间和数字输入框样式 */
:deep(.ant-input-number) {
width: 100%;
}
:deep(.ant-picker) {
width: 100%;
}
</style>

View File

@ -0,0 +1,84 @@
<!-- 弹出层表单 -->
<template>
<div style="margin: 20px auto">
<a-button type="primary" @click="openPopup" class="mr-2"> 打开弹窗 </a-button>
</div>
<!-- 自定义弹窗组件 -->
<BasicModal @register="registerModal" title="弹出层表单">
<!-- 自定义表单 -->
<BasicForm @register="registerForm" />
</BasicModal>
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
import { BasicModal } from '/@/components/Modal';
import { useModal } from '/@/components/Modal';
//
const formSchemas: FormSchema[] = [
{
label: '员工姓名',
field: 'name',
component: 'Input',
},
{
label: '性别',
field: 'sex',
component: 'Select',
//
componentProps: {
options: [
{ label: '男', value: 1 },
{ label: '女', value: 2 },
{ label: '未知', value: 3 },
],
},
//
defaultValue: 3,
},
{
label: '年龄',
field: 'age',
component: 'Input',
},
{
label: '入职时间',
subLabel: '( 选填 )',
field: 'entryTime',
component: 'TimePicker',
},
];
//BasicModal;
const [registerModal, { openModal }] = useModal();
/**
* BasicForm绑定注册;
*/
const [registerForm, { validate, resetFields }] = useForm({
schemas: formSchemas,
//
showActionButtonGroup: false,
});
/**
* 打开弹窗
*/
async function openPopup() {
// BasicModal
openModal(true, {});
}
</script>
<style scoped>
/** 时间和数字输入框样式 */
:deep(.ant-input-number) {
width: 100%;
}
:deep(.ant-picker) {
width: 100%;
}
</style>

View File

@ -0,0 +1,90 @@
<!-- 自定义渲染 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin-top: 20px">
<!-- #phone对应的是formSchemas对应slot(phone)插槽 -->
<template #phone="{ model, field }">
<!-- 如果是组件需要进行双向绑定model当前表单对象field当前字段名称 -->
<a-input v-model:value="model[field]" placeholder="请输入手机号" />
<span class="font-color">请输入您的手机号方便我们联系您</span>
</template>
<template #feedback="{ model, field }">
<JEditor v-model:value="model[field]" placeholder="请输入问题反馈" />
<span class="font-color">请您图文并茂方便我们了解问题并及时反馈</span>
</template>
</BasicForm>
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
import JEditor from '/@/components/Form/src/jeecg/components/JEditor.vue';
import { h } from 'vue';
import { Input } from 'ant-design-vue';
//
const formSchemas: FormSchema[] = [
{
field: 'productName',
label: '商品名称',
component: 'Input',
},
{
field: 'price',
label: '价格',
component: 'InputNumber',
},
{
field: 'buyNums',
label: '购买个数',
component: 'InputNumber',
//model field
render: ({ model, field }) => {
//Input
return h(Input, {
placeholder: '请输入购买个数',
value: model[field],
style: { width: '100%' },
type: 'number',
onChange: (e: ChangeEvent) => {
model[field] = e.target.value;
},
});
},
},
{
field: 'describe',
label: '描述',
component: 'Input',
componentProps: {
disabled: true,
},
// values
render: ({ values }) => {
let productName = values.productName?values.productName:'';
let price = values.price ? values.price : 0;
let buyNums = values.buyNums ? values.buyNums : 0;
return '购买商品名称:' + productName + ', 总价格: ' + price * buyNums + '元';
},
},
];
/**
* BasicForm绑定注册;
*/
const [registerForm] = useForm({
//
schemas: formSchemas,
showResetButton: false,
labelWidth: '150px',
submitButtonOptions: { text: '提交', preIcon: '' },
actionColOptions: { span: 17 },
});
</script>
<style scoped>
/** 数字输入框样式 */
:deep(.ant-input-number) {
width: 100%;
}
</style>

View File

@ -0,0 +1,58 @@
<!-- 表单验证 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin-top: 20px" @submit="handleSubmit" />
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
//
const formSchemas: FormSchema[] = [
{
field: 'visitor',
label: '来访人员',
component: 'Input',
//
required: true,
//
rulesMessageJoinLabel: false,
},
{
field: 'accessed',
label: '来访日期',
component: 'DatePicker',
// values
required: ({ values }) => {
return !values.accessed;
},
},
{
field: 'phone',
label: '来访人手机号',
component: 'Input',
//pattern message
rules: [{ required: false, message: '请输入正确的手机号', pattern: /^1[3456789]\d{9}$/ }],
},
];
/**
* BasicForm绑定注册;
*/
const [registerForm] = useForm({
//
schemas: formSchemas,
showResetButton: false,
labelWidth: '150px',
submitButtonOptions: { text: '提交', preIcon: '' },
actionColOptions: { span: 17 },
});
/**
* 提交事件
*/
function handleSubmit(values: any) {}
</script>
<style scoped></style>

View File

@ -0,0 +1,99 @@
<!-- 操作表单schemas配置 -->
<template>
<div style="margin: 20px auto; text-align: center">
<a-button @click="updateFormSchemas" class="mr-2"> 更新字段属性 </a-button>
<a-button @click="resetFormSchemas" class="mr-2"> 重置字段属性 </a-button>
</div>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin-top: 20px" />
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
//
const formSchemas: FormSchema[] = [
{
field: 'visitor',
label: '来访人员',
component: 'Input',
componentProps: {
disabled: true,
},
},
{
field: 'accessed',
label: '来访日期',
component: 'DatePicker',
ifShow: false,
},
{
field: 'phone',
label: '来访人手机号',
component: 'Input',
required: true,
},
];
/**
* BasicForm绑定注册;
* updateSchema 更新字段属性支持schemas里面所有的配置
* updateSchema([{ field: 'visitor', componentProps: { disabled: false },}, ... ]);
* resetSchema 重置字段属性支持schemas里面所有的配置
* resetSchema([{ field: 'visitor',label: '来访人员',component: 'Input',},... ]);
*/
const [registerForm, { updateSchema, resetSchema }] = useForm({
schemas: formSchemas,
//
showActionButtonGroup: false,
labelWidth: '150px',
//input
autoFocusFirstItem: true,
});
/**
* 清除表单配置
*/
async function resetFormSchemas() {
await resetSchema([
{
//
field: 'visitor',
label: '来访人员',
component: 'Input',
},
]);
}
/**
* 更新表单配置
*/
async function updateFormSchemas() {
//schemas
await updateSchema([
{
//
field: 'visitor',
componentProps: {
disabled: false,
},
},
{
field: 'accessed',
ifShow: true,
},
]);
}
</script>
<style scoped>
/** 时间和数字输入框样式 */
:deep(.ant-input-number) {
width: 100%;
}
:deep(.ant-picker) {
width: 100%;
}
</style>

View File

@ -0,0 +1,116 @@
<!-- 查询区域 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" @submit="handleSubmit" style="margin-top: 20px" />
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
//
const formSchemas: FormSchema[] = [
{
field: 'name',
label: '姓名',
component: 'Input',
},
{
field: 'hobby',
label: '爱好',
component: 'Input',
},
{
field: 'birthday',
label: '生日',
component: 'DatePicker',
},
{
field: 'joinTime',
label: '入职时间',
component: 'RangePicker',
componentProps: {
valueType: 'Date',
},
},
{
field: 'workYears',
label: '工作年份',
component: 'JRangeNumber',
},
{
field: 'sex',
label: '性别',
component: 'Select',
componentProps: {
options: [
{
label: '男',
value: '1',
},
{
label: '女',
value: '2',
},
],
},
},
{
field: 'marital',
label: '婚姻状况',
component: 'RadioGroup',
componentProps: {
options: [
{
label: '未婚',
value: '1',
},
{
label: '已婚',
value: '2',
},
],
},
},
];
/**
* BasicForm绑定注册;
*/
const [registerForm] = useForm({
// 2, 'YYYY-MM-DD'
fieldMapToTime: [['joinTime', ['joinTime_begin', 'joinTime_end'], 'YYYY-MM-DD']],
//
schemas: formSchemas,
//false
showAdvancedButton: true,
//3
autoAdvancedCol: 3,
//1
alwaysShowLines: 2,
// 2
fieldMapToNumber: [['workYears', ['workYears_begin', 'workYears_end']]],
//24
baseColProps: { span: 12 },
});
/**
* 点击提交按钮的value值
* @param values
*/
function handleSubmit(values: any) {
console.log('提交按钮数据::::', values);
}
</script>
<style scoped>
/** 时间和数字输入框样式 */
:deep(.ant-input-number) {
width: 100%;
}
:deep(.ant-picker) {
width: 100%;
}
</style>

View File

@ -0,0 +1,63 @@
<!-- 插槽 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin-top: 20px">
<!-- #phone对应的是formSchemas对应slot(phone)插槽 -->
<template #phone="{ model, field }">
<!-- 如果是组件需要进行双向绑定model当前表单对象field当前字段名称 -->
<a-input v-model:value="model[field]" placeholder="请输入手机号" />
<span class="font-color">请输入您的手机号方便我们联系您</span>
</template>
<template #feedback="{ model, field }">
<JEditor v-model:value="model[field]" placeholder="请输入问题反馈" />
<span class="font-color">请您图文并茂方便我们了解问题并及时反馈</span>
</template>
</BasicForm>
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
import JEditor from '/@/components/Form/src/jeecg/components/JEditor.vue';
//
const formSchemas: FormSchema[] = [
{
field: 'name',
label: '姓名',
component: 'Input',
},
{
field: 'phone',
label: '联系方式',
component: 'Input',
slot: 'phone',
},
{
field: 'feedback',
label: '问题反馈',
component: 'InputTextArea',
slot: 'feedback',
},
];
/**
* BasicForm绑定注册;
*/
const [registerForm] = useForm({
//
schemas: formSchemas,
showResetButton: false,
labelWidth: '150px',
submitButtonOptions: { text: '提交', preIcon: '' },
actionColOptions: { span: 17 },
});
</script>
<style scoped>
.font-color {
font-size: 13px;
color: #a1a1a1;
margin-bottom: 5px;
}
</style>

View File

@ -0,0 +1,94 @@
<!-- 操作表单值 -->
<template>
<div style="margin: 20px auto; text-align: center">
<a-button @click="getFormValue" class="mr-2"> 获取表单值 </a-button>
<a-button @click="clearFormValue" class="mr-2"> 清空表单值 </a-button>
<a-button @click="updateFormValue" class="mr-2"> 更新表单值 </a-button>
</div>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin-top: 20px" />
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
//
const formSchemas: FormSchema[] = [
{
field: 'visitor',
label: '来访人员',
component: 'Input',
required: true,
},
{
field: 'accessed',
label: '来访日期',
component: 'DatePicker',
required: true,
},
{
field: 'phone',
label: '来访人手机号',
component: 'Input',
required: true,
},
];
/**
* BasicForm绑定注册;
* getFieldsValue 获取所有表单值
* validate 验证通过之后的表单值,支持验证其中几个字段validate(['visitor',...])
* setFieldsValue 更新表单值 setFieldsValue({'visitor':'李四',...})
* resetFields 清除所有表单值
*/
const [registerForm, { getFieldsValue, setFieldsValue, resetFields, validate }] = useForm({
schemas: formSchemas,
//
showActionButtonGroup: false,
labelWidth: '150px',
//input
autoFocusFirstItem: true,
});
/**
* 获取表单值
*/
async function getFormValue() {
//
let fieldsValue = await getFieldsValue();
console.log('fieldsValue:::', fieldsValue);
//
fieldsValue = await validate();
console.log('fieldsValue:::', fieldsValue);
//`visitor访`
fieldsValue = await validate(['visitor']);
console.log('fieldsValue:::', fieldsValue);
}
/**
* 清空表单值
*/
async function clearFormValue() {
await resetFields();
}
/**
* 更新表单值
*/
async function updateFormValue() {
console.log('我进来了');
await setFieldsValue({ visitor: '李四' });
}
</script>
<style scoped>
/** 时间和数字输入框样式 */
:deep(.ant-input-number) {
width: 100%;
}
:deep(.ant-picker) {
width: 100%;
}
</style>

View File

@ -0,0 +1,63 @@
<!-- 基本用法 -->
<template>
<!-- 自定表单 -->
<BasicForm @register="registerForm" @submit="handleSubmit" style="margin-top: 20px" />
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
//
const formSchemas: FormSchema[] = [
{
//
label: '用户名(后面根据labelLength定义的长度隐藏)',
//
field: 'username',
//
component: 'Input',
//,
labelWidth: 150,
//
labelLength: 3,
},
{
label: '密码',
field: 'password',
//
subLabel: '(数字和字母组成)',
component: 'InputPassword',
labelWidth: '150px',
},
];
/**
* BasicForm绑定注册;
* useForm 是整个框架的核心用于表单渲染里边封装了很多公共方法;
* 支持schemas: 渲染表单列autoSubmitOnEnter回车提交,submitButtonOptions自定义按钮文本和图标等方法
* 平台通过此封装简化了代码支持自定义扩展;
*/
const [registerForm] = useForm({
//
schemas: formSchemas,
//
autoSubmitOnEnter: true,
//
showResetButton: false,
//
submitButtonOptions: { text: '提交', preIcon: '' },
// 24 0-24
actionColOptions: { span: 17 },
});
/**
* 点击提交按钮的value值
* @param values
*/
function handleSubmit(values: any) {
console.log('提交按钮数据::::', values);
}
</script>
<style scoped></style>

View File

@ -0,0 +1,393 @@
import { FormSchema } from '/@/components/Form';
import dayjs from 'dayjs';
export const schemas: FormSchema[] = [
{
label: '文本框',
field: 'name',
component: 'Input',
componentProps: {
prefix: '中文',
showCount: true,
},
defaultValue: '张三',
},
{
label: '密码',
field: 'password',
component: 'InputPassword',
componentProps: {
//是否显示切换按钮或者控制密码显隐
visibilityToggle: true,
prefix: '密码',
},
},
{
label: '搜索框',
field: 'searchBox',
component: 'InputSearch',
componentProps: {
onSearch: (value) => {
console.log(value);
},
},
},
{
label: '文本域',
field: 'textArea',
component: 'InputTextArea',
componentProps: {
//可以点击清除图标删除内容
allowClear: true,
//是否展示字数
showCount: true,
//自适应内容高度,可设置为 true | false 或对象:{ minRows: 2, maxRows: 6 }
autoSize: {
//最小显示行数
minRows: 2,
//最大显示行数
maxRows: 3,
},
},
},
{
label: '数值输入框',
field: 'number',
component: 'InputNumber',
componentProps: {
//带标签的 input设置后置标签
addonAfter: '保留两位小数',
//最大值
max: 100,
//数值经度
precision: 2,
//步数
step: 0.1,
},
},
{
label: '下拉框',
field: 'jinputtype',
component: 'Select',
componentProps: {
options: [
{ value: 'like', label: '模糊like' },
{ value: 'ne', label: '不等于ne' },
{ value: 'ge', label: '大于等于ge' },
{ value: 'le', label: '小于等于le)' },
],
//下拉多选
mode: 'multiple',
//配置是否可搜索
showSearch: true,
},
},
{
field: 'TreeSelect',
label: '下拉树',
component: 'TreeSelect',
componentProps: {
//是否显示下拉框默认false
treeCheckable: true,
//标题
title: '下拉树',
//下拉树
treeData: [
{
label: '洗衣机',
value: '0',
children: [
{
label: '滚筒洗衣机',
value: '0-1',
},
],
},
{
label: '电视机',
value: '1',
children: [
{
label: '平板电视',
value: '1-1',
disabled: true,
},
{
label: 'CRT电视机',
value: '1-2',
},
{
label: '投影电视',
value: '1-3',
},
],
},
],
},
},
{
label: 'RadioButtonGroup组件',
field: 'status',
component: 'RadioButtonGroup',
componentProps: {
options: [
{ label: '有效', value: 1 },
{ label: '无效', value: 0 },
],
},
},
{
label: '单选框',
field: 'radioSex',
component: 'RadioGroup',
componentProps: {
//options里面由一个一个的radio组成,支持disabled禁用
options: [
{ label: '男', value: 1, disabled: false },
{ label: '女', value: 0 },
],
},
},
{
label: '多选框',
field: 'checkbox',
component: 'Checkbox',
componentProps: {
//是否禁用,默认false
disabled: false,
},
},
{
label: '多选框组',
field: 'checkSex',
component: 'CheckboxGroup',
componentProps: {
//RadioGroup 下所有 input[type="radio"] 的 name 属性
name: '爱好',
//options支持disabled禁用
options: [
{ label: '运动', value: 0, disabled: true },
{ label: '听音乐', value: 1 },
{ label: '看书', value: 2 },
],
},
defaultValue: [2],
},
{
label: '自动完成组件',
field: 'AutoComplete',
component: 'AutoComplete',
componentProps: {
options: [{ value: 'Burns Bay Road' }, { value: 'Downing Street' }, { value: 'Wall Street' }],
},
},
{
label: '级联选择',
field: 'cascade',
component: 'Cascader',
componentProps: {
//最多显示多少个tag
maxTagCount: 2,
//浮层预设位置
placement: 'bottomRight',
//在选择框中显示搜索框,默认false
showSearch: true,
options: [
{
label: '北京',
value: 'BeiJin',
children: [
{
label: '海淀区',
value: 'HaiDian',
},
],
},
{
label: '江苏省',
value: 'JiangSu',
children: [
{
label: '南京',
value: 'Nanjing',
children: [
{
label: '中华门',
value: 'ZhongHuaMen',
},
],
},
],
},
],
},
},
{
label: '日期选择',
field: 'dateSelect',
component: 'DatePicker',
componentProps: {
//日期格式化,页面上显示的值
format: 'YYYY-MM-DD',
//返回值格式化(绑定值的格式)
valueFormat: 'YYYY-MM-DD',
//是否显示今天按钮
showToday: true,
//不可选择日期
disabledDate: (currentDate) => {
let date = dayjs(currentDate).format('YYYY-MM-DD');
let nowDate = dayjs(new Date()).format('YYYY-MM-DD');
//当天不可选择
if (date == nowDate) {
return true;
}
return false;
},
},
},
{
label: '月份选择',
field: 'monthSelect',
component: 'MonthPicker',
componentProps: {
//不可选择日期
disabledDate: (currentDate) => {
let date = dayjs(currentDate).format('YYYY-MM');
let nowDate = dayjs(new Date()).format('YYYY-MM');
//当天不可选择
if (date == nowDate) {
return true;
}
return false;
},
},
},
{
label: '周选择',
field: 'weekSelect',
component: 'WeekPicker',
componentProps: {
size: 'small',
},
},
{
label: '时间选择',
field: 'timeSelect',
component: 'TimePicker',
componentProps: {
size: 'default',
//日期时间或者时间模式下是否显示此刻,不支持日期时间范围和时间范围
showNow: true,
},
},
{
label: '日期时间范围',
field: 'dateTimeRangeSelect',
component: 'RangePicker',
componentProps: {
//是否显示时间
showTime: true,
//日期格式化
format: 'YYYY/MM/DD HH:mm:ss',
//范围文本描述用集合
placeholder: ['请选择开始日期时间', '请选择结束日期时间'],
},
},
{
label: '日期范围',
field: 'dateRangeSelect',
component: 'RangeDate',
componentProps: {
//日期格式化
format: 'YYYY/MM/DD',
//范围文本描述用集合
placeholder: ['请选择开始日期', '请选择结束日期'],
},
},
{
label: '时间范围',
field: 'timeRangeSelect',
component: 'RangeTime',
componentProps: {
//日期格式化
format: 'HH/mm/ss',
//范围文本描述用集合
placeholder: ['请选择开始时间', '请选择结束时间'],
},
},
{
label: '开关',
field: 'switch',
component: 'Switch',
componentProps: {
//开关大小可选值default small
size: 'default',
//非选中时的内容
unCheckedChildren: '开启',
//非选中时的值
unCheckedValue: '0',
//选中时的内容
checkedChildren: '关闭',
//选中时的值
checkedValue: '1',
//是否禁用
disabled: false,
},
},
{
label: '滑动输入条',
field: 'slider',
component: 'Slider',
componentProps: {
//最小值
min: -20,
//最大值
max: 100,
//是否为双滑块模式
range: true,
//刻度标记
marks: {
'-20': '-20°C',
0: '0°C',
26: '26°C',
37: '37°C',
100: {
style: {
color: '#f50',
},
label: '100°C',
},
},
},
},
{
label: '评分',
field: 'rate',
component: 'Rate',
componentProps: {
//是否允许半选
allowHalf: true,
//star 总数
count: 5,
//tooltip提示有几颗星写几个
tooltips: ['非常差', '较差', '正常', '很好', '非很好'],
},
},
{
label: '分割线',
field: 'divisionLine',
component: 'Divider',
componentProps: {
//是否虚线
dashed: false,
//分割线标题的位置left | right | center
orientation: 'center',
//文字是否显示为普通正文样式
plain: true,
//水平还是垂直类型horizontal | vertical
type: 'horizontal',
},
},
];

View File

@ -0,0 +1,452 @@
import { FormSchema } from '/@/components/Form';
import { defHttp } from '/@/utils/http/axios';
export const schemas: FormSchema[] = [
{
label: '验证码',
field: 'code',
component: 'InputCountDown',
componentProps: {
//'default': 默认, 'large': 最大, 'small': 最小
size:'default',
//倒计时
count: 120,
},
},
{
label: 'Api下拉选择',
field: 'apiSelect',
component: 'ApiSelect',
componentProps: {
//multiple: 多选;不填写为单选
mode: 'multiple',
//请求api,返回结果{ result: { records:[{'id':'1',name:'scott'},{'id':'2',name:'小张'}] }}
api: () => defHttp.get({ url: '/test/jeecgDemo/list' }),
//数值转成String
numberToString: false,
//标题字段
labelField: 'name',
//值字段
valueField: 'id',
//请求参数
params: {},
//返回结果字段
resultField: 'records',
},
},
{
label: 'Api树选择',
field: 'apiSelect',
component: 'ApiTreeSelect',
componentProps: {
/* api,
{ result: { list: [{ title:'选项0',value:'0',key:'0',
children: [ {"title": "选项0-0","value": "0-0","key": "0-0"},...]
}, ...]
}} */
api: () => defHttp.get({ url: '/mock/tree/getDemoOptions' }),
//请求参数
params: {},
//返回结果字段
resultField: 'list',
},
},
{
label: '校验密码强度',
field: 'pwd',
component: 'StrengthMeter',
componentProps: {
//是否显示密码文本框
showInput: true,
//是否禁用
disabled: false,
},
},
{
label: '省市县联动',
field: 'province',
component: 'JAreaLinkage',
componentProps: {
//是否显示区县默认true,否则只显示省
showArea: true,
//是否是全部文本默认false
showAll: true,
},
},
{
label: '岗位选择',
field: 'post',
component: 'JSelectPosition',
componentProps: {
//是否右侧显示选中列表
showSelected: true,
//最大选择数量
maxSelectCount: 1,
//岗位标题
modalTitle: '岗位',
},
},
{
label: '角色选择',
field: 'role',
component: 'JSelectRole',
componentProps: {
//请求参数 如params:{"code":"001"}
params: {},
//是否单选,默认false
isRadioSelection: true,
//角色标题
modalTitle: '角色',
},
},
{
label: '用户选择',
field: 'user',
component: 'JSelectUser',
componentProps: {
//取值字段配置,一般为主键字段
rowKey: 'username',
//显示字段配置
labelKey: 'realname',
//是否显示选择按钮
showButton: false,
//用户标题
modalTitle: '用户',
},
},
{
label: '图片上传',
field: 'uploadImage',
component: 'JImageUpload',
componentProps: {
//按钮显示文字
text:'图片上传',
//支持两种基本样式picture和picture-card
listType:'picture-card',
//用于控制文件上传的业务路径,默认temp
bizPath:'temp',
//是否禁用
disabled:false,
//最大上传数量
fileMax:1,
},
},
{
label: '字典标签',
field: 'dictTags',
component: 'JDictSelectTag',
componentProps: {
//字典code配置比如通过性别字典编码sex也可以使用demo,name,id 表名,名称,值的方式
dictCode:'sex',
//支持radio(单选按钮)、radioButton(单选按钮 btn风格)、select(下拉框)
type:'radioButton'
},
},
{
label: '部门选择',
field: 'dept',
component: 'JSelectDept',
componentProps: {
//是否开启异步加载
sync: false,
//是否显示复选框
checkable: true,
//是否显示选择按钮
showButton: false,
//父子节点选中状态不再关联
checkStrictly: true,
//选择框标题
modalTitle: '部门选择',
},
},
{
label: '省市县级联动',
field: 'provinceArea',
component: 'JAreaSelect',
componentProps: {
//级别 1 只显示省 2 省市 3 省市区
level:3
},
},
{
label: '富文本',
field: 'editor',
component: 'JEditor',
componentProps: {
//是否禁用
disabled: false
},
},
{
label: 'markdown',
field: 'markdown',
component: 'JMarkdownEditor',
componentProps: {
//是否禁用
disabled: false
},
},
{
label: '可输入下拉框',
field: 'inputSelect',
component: 'JSelectInput',
componentProps: {
options: [
{ label: 'Default', value: 'default' },
{ label: 'IFrame', value: 'iframe' },
],
//是否为搜索模式
showSearch: true,
//是否禁用
disabled: false
},
},
{
label: '代码编辑器组件',
field: 'jCode',
component: 'JCodeEditor',
componentProps: {
//高度默认auto
height:'150px',
//是否禁用
disabled:false,
//是否全屏
fullScreen:false,
//全屏之后的坐标
zIndex: 999,
//代码主题目前只支持idea,可在组件自行扩展
theme:'idea',
//代码提示
keywords:['console'],
//语言如javascript,vue,markdown可在组件自行扩展
language:'javascript'
},
},
{
label: '分类字典树',
field: 'dictTree',
component: 'JCategorySelect',
componentProps: {
//占位内容
placeholder:'请选择分类字典树',
//查询条件,如“{'name':'笔记本'}”
condition:"",
//是否多选
multiple: false,
//起始选择code见配置的分类字典的类型编码
pcode: 'A04',
//父级id
pid:'',
//返回key
back:'id',
},
},
{
label: '下拉多选',
field: 'selectMultiple',
component: 'JSelectMultiple',
componentProps: {
//字典code配置比如通过性别字典编码sex也可以使用demo,name,id 表名,名称,值的方式
dictCode:'company_rank',
//是否只读
readOnly:false,
},
},
{
label: 'popup',
field: 'popup',
component: 'JPopup',
componentProps: ({ formActionType }) => {
const {setFieldsValue} = formActionType;
return{
setFieldsValue:setFieldsValue,
//online报表编码
code:"demo",
//是否为多选
multi:false,
//字段配置
fieldConfig: [
{ source: 'name', target: 'popup' },
],
}
},
},
{
label: '开关自定义',
field: 'switch',
component: 'JSwitch',
componentProps:{
//取值 options
options:['Y','N'],
//文本option
labelOptions:['是', '否'],
//是否启用下拉
query: false,
//是否禁用
disabled: false,
},
},
{
label: '定时表达式选择',
field: 'timing',
component: 'JEasyCron',
componentProps:{
//是否隐藏参数秒和年设置,如果隐藏,那么参数秒和年将会全部忽略掉。
hideSecond: false,
//是否隐藏参数年设置,如果隐藏,那么参数年将会全部忽略掉
hideYear: false,
//是否禁用
disabled: false,
//获取预览执行时间列表的函数格式为remote (cron值, time时间戳, cb回调函数)
remote:(cron,time,cb)=>{}
},
},
{
label: '分类字典树',
field: 'treeDict',
component: 'JTreeDict',
componentProps:{
//指定当前组件需要存储的字段 可选: id(主键)和code(编码)
field:'id',
//是否为异步
async: true,
//是否禁用
disabled: false,
//指定一个节点的编码,加载该节点下的所有字典数据,若不指定,默认加载所有数据
parentCode:'A04'
},
},
{
label: '多行输入窗口',
field: 'inputPop',
component: 'JInputPop',
componentProps:{
//标题
title:'多行输入窗口',
//弹窗显示位置
position:'bottom',
},
},
{
label: '多选',
field: 'multipleChoice',
component: 'JCheckbox',
componentProps:{
//字典code配置比如通过职位字典编码company_rank也可以使用demo,name,id 表名,名称,值的方式
dictCode:'company_rank',
//是否禁用
disabled: false,
//没有字典code可以使用option来定义
// options:[
// {label:'CE0',value:'1'}
// ]
},
},
{
label: '下拉树选择',
field: 'treeCusSelect',
component: 'JTreeSelect',
componentProps: {
//字典code配置比如通过性别字典编码sex也可以使用sys_permission,name,id 表名,名称,值的方式
dict: 'sys_permission,name,id',
//父级id字段
pidField: 'parent_id',
},
},
{
label: '根据部门选择用户组件',
field: 'userByDept',
component: 'JSelectUserByDept',
componentProps: {
//是否显示选择按钮
showButton: true,
//选择框标题
modalTitle: '部门用户选择'
},
},
{
label: '文件上传',
field: 'uploadFile',
component: 'JUpload',
componentProps: {
//是否显示选择按钮
text: '文件上传',
//最大上传数
maxCount: 2,
//是否显示下载按钮
download: true,
},
},
{
label: '字典表搜索',
field: 'dictSearchSelect',
component: 'JSearchSelect',
componentProps: {
//字典code配置通过 demo,name,id 表名,名称,值的方式
dict: 'demo,name,id',
//是否异步加载
async: true,
//当async设置为true时有效表示异步查询时每次获取数据的数量默认10
pageSize:3
},
},
{
label: '动态创建input框',
field: 'jAddInput',
component: 'JAddInput',
componentProps: {
//自定义超过多少行才会显示删除按钮默认为1
min:1
},
},
{
label: '用户选择组件',
field: 'userCusSelect',
component: 'UserSelect',
componentProps: {
//是否多选
multi: true,
//从用户表中选择一列其值作为该控件的存储值默认id列
store: 'id',
//是否排除我自己(当前登录用户)
izExcludeMy: false,
//是否禁用
disabled: false,
},
},
{
label: '选择角色组件',
field: 'roleSelect',
component: 'RoleSelect',
componentProps: {
//最大选择数量
maxSelectCount: 3,
//是否单选
isRadioSelection: false
},
},
{
label: '数值范围输入框',
field: 'rangeNumber',
component: 'JRangeNumber',
},
{
label: '远程Api单选框组',
field: 'apiRadioGroup',
component: 'ApiRadioGroup',
componentProps:{
//请求接口返回结果{ result:{ list: [ name: '选项0',id: '1' ] }}
api:()=> defHttp.get({ url: '/mock/select/getDemoOptions' }),
//请求参数
params:{},
//是否为按钮风格类型默认false
isBtn: false,
//返回集合名称
resultField: 'list',
//标题字段名称
labelField: 'name',
//值字段名称
valueField: 'id',
}
},
];

View File

@ -0,0 +1,24 @@
export { default as BasicFiledsLayotForm } from './BasicFiledsLayotForm.vue';
export { default as BasicFixedWidthForm } from './BasicFixedWidthForm.vue';
export { default as BasicFormAdd } from './BasicFormAdd.vue';
export { default as BasicFormBtn } from './BasicFormBtn.vue';
export { default as BasicFormCleanRule } from './BasicFormCleanRule.vue';
export { default as BasicFormCompact } from './BasicFormCompact.vue';
export { default as BasicFormComponent } from './BasicFormComponent.vue';
export { default as BasicFormConAttribute } from './BasicFormConAttribute.vue';
export { default as BasicFormCustom } from './BasicFormCustom.vue';
export { default as BasicFormCustomComponent } from './BasicFormCustomComponent.vue';
export { default as BasicFormCustomSlots } from './BasicFormCustomSlots.vue';
export { default as BasicFormDynamicsRules } from './BasicFormDynamicsRules.vue';
export { default as BasicFormFieldShow } from './BasicFormFieldShow.vue';
export { default as BasicFormFieldTip } from './BasicFormFieldTip.vue';
export { default as BasicFormFooter } from './BasicFormFooter.vue';
export { default as BasicFormLayout } from './BasicFormLayout.vue';
export { default as BasicFormModal } from './BasicFormModal.vue';
export { default as BasicFormRander } from './BasicFormRander.vue';
export { default as BasicFormRules } from './BasicFormRules.vue';
export { default as BasicFormSchemas } from './BasicFormSchemas.vue';
export { default as BasicFormSearch } from './BasicFormSearch.vue';
export { default as BasicFormSlots } from './BasicFormSlots.vue';
export { default as BasicFormValue } from './BasicFormValue.vue';
export { default as BasicFunctionForm } from './BasicFunctionForm.vue';

View File

@ -0,0 +1,114 @@
<template>
<div class="p-4">
<a-card :bordered="false" style="height: 100%">
<a-tabs v-model:activeKey="activeKey" @change="tabChange">
<a-tab-pane :key="item.key" :tab="item.label" v-for="item in compList" />
</a-tabs>
<component :is="currentComponent" />
</a-card>
</div>
</template>
<script lang="ts">
import { defineComponent, ref, computed } from 'vue';
import {
BasicFunctionForm,
BasicFormConAttribute,
BasicFormFieldShow,
BasicFormFieldTip,
BasicFormRules,
BasicFormDynamicsRules,
BasicFormSlots,
BasicFormCustomSlots,
BasicFormRander,
BasicFixedWidthForm,
BasicFiledsLayotForm,
BasicFormLayout,
BasicFormBtn,
BasicFormCompact,
BasicFormCleanRule,
BasicFormValue,
BasicFormSchemas,
BasicFormAdd,
BasicFormFooter,
BasicFormModal,
BasicFormCustom,
BasicFormSearch,
BasicFormComponent,
BasicFormCustomComponent,
} from './index';
export default defineComponent({
name: 'document-table-demo',
components: {
BasicFunctionForm,
BasicFormConAttribute,
BasicFormFieldShow,
BasicFormFieldTip,
BasicFormRules,
BasicFormDynamicsRules,
BasicFormSlots,
BasicFormCustomSlots,
BasicFormRander,
BasicFixedWidthForm,
BasicFiledsLayotForm,
BasicFormLayout,
BasicFormBtn,
BasicFormCompact,
BasicFormCleanRule,
BasicFormValue,
BasicFormSchemas,
BasicFormAdd,
BasicFormFooter,
BasicFormModal,
BasicFormCustom,
BasicFormSearch,
BasicFormComponent,
BasicFormCustomComponent,
},
setup() {
//key
const activeKey = ref('BasicFunctionForm');
//
const compList = ref([
{ key: 'BasicFunctionForm', label: '基础表单' },
{ key: 'BasicFormConAttribute', label: '字段控件属性' },
{ key: 'BasicFormComponent', label: 'Ant Design Vue自带控件' },
{ key: 'BasicFormCustomComponent', label: 'JEECG封装的控件' },
{ key: 'BasicFormFieldShow', label: '字段显示和隐藏' },
{ key: 'BasicFormFieldTip', label: '字段标题提示' },
{ key: 'BasicFormRules', label: '表单检验' },
{ key: 'BasicFormDynamicsRules', label: '自定义动态检验' },
{ key: 'BasicFormSlots', label: '字段插槽' },
{ key: 'BasicFormCustomSlots', label: '自定义组件(插槽)' },
{ key: 'BasicFormCustom', label: '自定义组件(component)' },
{ key: 'BasicFormRander', label: '自定义渲染' },
{ key: 'BasicFixedWidthForm', label: '固定label宽度' },
{ key: 'BasicFiledsLayotForm', label: '标题与字段布局' },
{ key: 'BasicFormLayout', label: '表单布局' },
{ key: 'BasicFormBtn', label: '操作按钮示例' },
{ key: 'BasicFormCompact', label: '表单紧凑' },
{ key: 'BasicFormCleanRule', label: '表单检验配置' },
{ key: 'BasicFormValue', label: '获取value值' },
{ key: 'BasicFormSchemas', label: '更新schemas表单配置' },
{ key: 'BasicFormAdd', label: '动态增减表单' },
{ key: 'BasicFormFooter', label: '自定义页脚' },
{ key: 'BasicFormModal', label: '弹出层表单' },
{ key: 'BasicFormSearch', label: '查询区域' },
]);
//
const currentComponent = computed(() => {
return activeKey.value;
});
//使componenttab
function tabChange(key) {
activeKey.value = key;
}
return {
activeKey,
currentComponent,
tabChange,
compList,
};
},
});
</script>

View File

@ -0,0 +1,135 @@
<template>
<div class="p-4">
<BasicTable @register="registerTable">
<template #action="{ record }">
<TableAction
:actions="[
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'demo:btn:show', // :
},
{
label: '删除',
icon: 'ic:outline-delete-outline',
onClick: handleDelete.bind(null, record),
auth: 'super', // :
},
]"
:dropDownActions="[
{
label: '启用',
popConfirm: {
title: '是否启用?',
confirm: handleOpen.bind(null, record),
},
ifShow: (_action) => {
return record.status !== 'enable'; // : enable
},
},
{
label: '禁用',
popConfirm: {
title: '是否禁用?',
confirm: handleOpen.bind(null, record),
},
ifShow: () => {
return record.status === 'enable'; // : enable
},
},
{
label: '同时控制',
popConfirm: {
title: '是否动态显示?',
confirm: handleOpen.bind(null, record),
},
auth: 'super', //
ifShow: () => {
return true;
},
},
]"
/>
</template>
</BasicTable>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicTable, useTable, BasicColumn, TableAction } from '/@/components/Table';
import { demoListApi } from '/@/api/demo/table';
import { useListPage } from '/@/hooks/system/useListPage';
const columns: BasicColumn[] = [
{
title: '编号',
dataIndex: 'no',
width: 100,
},
{
title: '姓名',
dataIndex: 'name',
auth: 'demo:field:show', // :
},
{
title: '状态',
dataIndex: 'status',
},
{
title: '地址',
dataIndex: 'address',
auth: 'super', //
ifShow: (_column) => {
return true;
},
},
{
title: '开始时间',
dataIndex: 'beginTime',
},
{
title: '结束时间',
dataIndex: 'endTime',
width: 200,
},
];
export default defineComponent({
components: { BasicTable, TableAction },
setup() {
const { tableContext } = useListPage({
tableProps: {
title: '权限列',
api: demoListApi,
columns: columns,
bordered: true,
useSearchForm: false,
actionColumn: {
width: 250,
title: 'Action',
dataIndex: 'action',
slots: { customRender: 'action' },
},
},
});
//table
const [registerTable] = tableContext;
function handleEdit(record: Recordable) {
console.log('点击了编辑', record);
}
function handleDelete(record: Recordable) {
console.log('点击了删除', record);
}
function handleOpen(record: Recordable) {
console.log('点击了启用', record);
}
return {
registerTable,
handleEdit,
handleDelete,
handleOpen,
};
},
});
</script>

View File

@ -0,0 +1,94 @@
<template>
<!--引用表格-->
<div class="p-4">
<BasicTable @register="registerTable">
<template #bodyCell="{ column, text }">
<template v-if="column.dataIndex === 'name'">
<a>{{ text }}</a>
</template>
</template>
<template #footer>页脚</template>
</BasicTable>
</div>
</template>
<script lang="ts" name="basic-table-demo" setup>
import { ActionItem, BasicColumn, BasicTable, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
//
const columns: BasicColumn[] = [
{
title: '姓名',
dataIndex: 'name',
key: 'name',
width: 300,
},
{
title: '年龄',
dataIndex: 'age',
key: 'age',
width: 300,
},
{
title: '住址',
dataIndex: 'address',
key: 'address',
ellipsis: true,
},
{
title: '长内容列',
dataIndex: 'address',
key: 'address 2',
ellipsis: true,
},
{
title: '长内容列',
dataIndex: 'address',
key: 'address 3',
ellipsis: true,
},
];
//
const { tableContext } = useListPage({
designScope: 'basic-table-demo',
tableProps: {
title: '边框表格',
dataSource: [
{
key: '1',
name: '张三',
age: 32,
address: '中国北京北京市朝阳区大屯路科学院南里1号楼3单元401',
},
{
key: '2',
name: '刘思',
age: 32,
address: '中国北京北京市昌平区顺沙路尚湖世家2号楼7单元503',
},
],
columns: columns,
showActionColumn: false,
useSearchForm: false,
},
});
//table
const [registerTable] = tableContext;
/**
* 操作栏
*/
function getTableAction(record): ActionItem[] {
return [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
},
];
}
function handleEdit(record) {
console.log(record);
}
</script>
<style scoped></style>

View File

@ -0,0 +1,81 @@
<template>
<div class="p-4">
<!--引用表格-->
<BasicTable @register="registerTable">
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" />
</template>
</BasicTable>
</div>
</template>
<script lang="ts" name="basic-table-demo" setup>
import { ActionItem, BasicColumn, BasicTable, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
//
const columns: BasicColumn[] = [
{
title: '姓名',
dataIndex: 'name',
key: 'name',
resizable: false,
},
{
title: '年龄',
dataIndex: 'age',
key: 'age',
},
{
title: '住址',
dataIndex: 'address',
key: 'address',
},
];
//
const { tableContext } = useListPage({
designScope: 'basic-table-demo',
tableProps: {
title: '用户列表',
dataSource: [
{
key: '1',
name: '胡歌',
age: 32,
address: '朝阳区林萃路1号',
},
{
key: '2',
name: '刘诗诗',
age: 32,
address: '昌平区白沙路1号',
},
],
columns: columns,
size: 'large', // large
striped: false, // false
showActionColumn: true,
useSearchForm: false,
},
});
//table
const [registerTable, methods] = tableContext;
console.log('methods', methods);
/**
* 操作栏
*/
function getTableAction(record): ActionItem[] {
return [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
},
];
}
function handleEdit(record) {
console.log(record);
}
</script>
<style scoped></style>

View File

@ -0,0 +1,157 @@
<template>
<div class="p-4">
<!--定义表格-->
<BasicTable @register="registerTable">
<!-- 搜索区域插槽自定义查询 -->
<template #form-email="{ model, field }">
<a-input placeholder="请输入邮箱" v-model:value="model[field]" addon-before=":" addon-after=".com"></a-input>
</template>
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" />
</template>
</BasicTable>
</div>
</template>
<script lang="ts" name="basic-table-demo" setup>
import { ActionItem, BasicColumn, BasicTable, FormSchema, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
import { defHttp } from '/@/utils/http/axios';
//
const columns: BasicColumn[] = [
{
title: '姓名',
dataIndex: 'name',
width: 170,
align: 'left',
resizable: true,
sorter: {
multiple: 1,
},
},
{
title: '关键词',
dataIndex: 'keyWord',
width: 130,
resizable: true,
},
{
title: '打卡时间',
dataIndex: 'punchTime',
width: 140,
resizable: true,
},
{
title: '工资',
dataIndex: 'salaryMoney',
width: 140,
resizable: true,
sorter: {
multiple: 2,
},
},
{
title: '奖金',
dataIndex: 'bonusMoney',
width: 140,
resizable: true,
},
{
title: '性别',
dataIndex: 'sex',
sorter: {
multiple: 3,
},
filters: [
{ text: '男', value: '1' },
{ text: '女', value: '2' },
],
customRender: ({ record }) => {
return record.sex ? (record.sex == '1' ? '男' : '女') : '';
},
width: 120,
resizable: true,
},
{
title: '生日',
dataIndex: 'birthday',
width: 120,
resizable: true,
},
{
title: '邮箱',
dataIndex: 'email',
width: 120,
resizable: true,
},
];
//
const searchFormSchema: FormSchema[] = [
{
label: '姓名', //label
field: 'name', //
component: 'JInput', //
defaultValue: '苏榕润', //
},
{
label: '性别',
field: 'sex',
component: 'JDictSelectTag',
componentProps: {
//props
dictCode: 'sex',
placeholder: '请选择性别',
},
},
{
label: '邮箱',
field: 'email',
component: 'JInput',
slot: 'email',
},
{
label: '生日',
field: 'birthday',
component: 'DatePicker',
},
];
//ajaxapi
const demoListApi = (params) => {
return defHttp.get({ url: '/test/jeecgDemo/list', params });
};
//
const { tableContext } = useListPage({
designScope: 'basic-table-demo-filter',
tableProps: {
title: '用户列表',
api: demoListApi,
columns: columns,
formConfig: {
schemas: searchFormSchema,
},
useSearchForm: true,
},
});
//BasicTable
const [registerTable, { getForm }] = tableContext;
/**
* 操作栏
*/
function getTableAction(record): ActionItem[] {
return [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
},
];
}
function handleEdit(record) {
let { getFieldsValue } = getForm();
console.log('查询form的数据', getFieldsValue());
console.log(record);
}
</script>
<style scoped></style>

View File

@ -0,0 +1,106 @@
<template>
<div class="p-4">
<BasicTable @register="registerTable">
<template #id="{ record }"> ID: {{ record.id }} </template>
<template #bodyCell="{ column, record }">
<Avatar v-if="column.key === 'avatar'" :size="60" :src="record.avatar" />
<Tag v-if="column.key === 'no'" color="green">
{{ record.no }}
</Tag>
</template>
<template #img="{ text }">
<TableImg :size="60" :simpleShow="true" :imgList="text" />
</template>
<template #imgs="{ text }"> <TableImg :size="60" :imgList="text" /> </template>
<template #category="{ record }">
<Tag color="green">
{{ record.no }}
</Tag>
</template>
</BasicTable>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicTable, useTable, BasicColumn, TableImg } from '/@/components/Table';
import { Tag, Avatar } from 'ant-design-vue';
import { demoListApi } from '/@/api/demo/table';
import { useListPage } from '/@/hooks/system/useListPage';
const columns: BasicColumn[] = [
{
title: 'ID',
dataIndex: 'id',
slots: { customRender: 'id' },
},
{
title: '头像',
dataIndex: 'avatar',
width: 100,
},
{
title: '分类',
dataIndex: 'category',
width: 80,
align: 'center',
defaultHidden: true,
slots: { customRender: 'category' },
},
{
title: '姓名',
dataIndex: 'name',
width: 120,
},
{
title: '图片列表1',
dataIndex: 'imgArr',
helpMessage: ['这是简单模式的图片列表', '只会显示一张在表格中', '但点击可预览多张图片'],
width: 140,
slots: { customRender: 'img' },
},
{
title: '照片列表2',
dataIndex: 'imgs',
width: 160,
slots: { customRender: 'imgs' },
},
{
title: '地址',
dataIndex: 'address',
},
{
title: '编号',
dataIndex: 'no',
},
{
title: '开始时间',
dataIndex: 'beginTime',
},
{
title: '结束时间',
dataIndex: 'endTime',
},
];
export default defineComponent({
components: { BasicTable, TableImg, Tag, Avatar },
setup() {
const { tableContext } = useListPage({
tableProps: {
title: '自定义列内容',
titleHelpMessage: '表格中所有头像、图片均为mock生成仅用于演示图片占位',
api: demoListApi,
columns: columns,
bordered: true,
showTableSetting: false,
showActionColumn: false,
useSearchForm: false,
},
});
//table
const [registerTable] = tableContext;
return {
registerTable,
};
},
});
</script>

View File

@ -0,0 +1,217 @@
<template>
<div class="p-4">
<BasicTable @register="registerTable" @edit-end="handleEditEnd" @edit-cancel="handleEditCancel" :beforeEditSubmit="beforeEditSubmit" />
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicTable, useTable, BasicColumn } from '/@/components/Table';
import { optionsListApi } from '/@/api/demo/select';
import { demoListApi } from '/@/api/demo/table';
import { treeOptionsListApi } from '/@/api/demo/tree';
import { useMessage } from '/@/hooks/web/useMessage';
import { useListPage } from '/@/hooks/system/useListPage';
const columns: BasicColumn[] = [
{
title: '输入框',
dataIndex: 'name',
edit: true,
editComponentProps: {
prefix: '$',
},
width: 200,
},
{
title: '默认输入状态',
dataIndex: 'name7',
edit: true,
editable: true,
width: 200,
},
{
title: '输入框校验',
dataIndex: 'name1',
edit: true,
//
editRule: true,
width: 200,
},
{
title: '输入框函数校验',
dataIndex: 'name2',
edit: true,
editRule: async (text) => {
if (text === '2') {
return '不能输入该值';
}
return '';
},
width: 200,
},
{
title: '数字输入框',
dataIndex: 'id',
edit: true,
editRule: true,
editComponent: 'InputNumber',
width: 200,
},
{
title: '下拉框',
dataIndex: 'name3',
edit: true,
editComponent: 'Select',
editComponentProps: {
options: [
{
label: 'Option1',
value: '1',
},
{
label: 'Option2',
value: '2',
},
],
},
width: 200,
},
{
title: '远程下拉',
dataIndex: 'name4',
edit: true,
editComponent: 'ApiSelect',
editComponentProps: {
api: optionsListApi,
resultField: 'list',
labelField: 'name',
valueField: 'id',
},
width: 200,
},
{
title: '远程下拉树',
dataIndex: 'name71',
edit: true,
editComponent: 'ApiTreeSelect',
editRule: false,
editComponentProps: {
api: treeOptionsListApi,
resultField: 'list',
},
width: 200,
},
{
title: '日期选择',
dataIndex: 'date',
edit: true,
editComponent: 'DatePicker',
editComponentProps: {
valueFormat: 'YYYY-MM-DD',
format: 'YYYY-MM-DD',
},
width: 200,
},
{
title: '时间选择',
dataIndex: 'time',
edit: true,
editComponent: 'TimePicker',
editComponentProps: {
valueFormat: 'HH:mm',
format: 'HH:mm',
},
width: 200,
},
{
title: '勾选框',
dataIndex: 'name5',
edit: true,
editComponent: 'Checkbox',
editValueMap: (value) => {
return value ? '是' : '否';
},
width: 200,
},
{
title: '开关',
dataIndex: 'name6',
edit: true,
editComponent: 'Switch',
editValueMap: (value) => {
return value ? '开' : '关';
},
width: 200,
},
];
export default defineComponent({
components: { BasicTable },
setup() {
//
const { tableContext } = useListPage({
designScope: 'basic-table-demo',
tableProps: {
title: '可编辑单元格示例',
api: demoListApi,
columns: columns,
showIndexColumn: false,
bordered: true,
showActionColumn: false,
useSearchForm: false,
},
});
//table
const [registerTable] = tableContext;
const { createMessage } = useMessage();
function handleEditEnd({ record, index, key, value }: Recordable) {
console.log(record, index, key, value);
return false;
}
//
function feakSave({ value, key, id }) {
createMessage.loading({
content: `正在模拟保存${key}`,
key: '_save_fake_data',
duration: 0,
});
return new Promise((resolve) => {
setTimeout(() => {
if (value === '') {
createMessage.error({
content: '保存失败:不能为空',
key: '_save_fake_data',
duration: 2,
});
resolve(false);
} else {
createMessage.success({
content: `记录${id}${key}已保存`,
key: '_save_fake_data',
duration: 2,
});
resolve(true);
}
}, 2000);
});
}
async function beforeEditSubmit({ record, index, key, value }) {
console.log('单元格数据正在准备提交', { record, index, key, value });
return await feakSave({ id: record.id, key, value });
}
function handleEditCancel() {
console.log('cancel');
}
return {
registerTable,
handleEditEnd,
handleEditCancel,
beforeEditSubmit,
};
},
});
</script>

View File

@ -0,0 +1,261 @@
<template>
<div class="p-4">
<BasicTable @register="registerTable" @edit-change="onEditChange">
<template #action="{ record, column }">
<TableAction :actions="createActions(record, column)" />
</template>
</BasicTable>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import { BasicTable, useTable, TableAction, BasicColumn, ActionItem, EditRecordRow } from '/@/components/Table';
import { optionsListApi } from '/@/api/demo/select';
import { demoListApi } from '/@/api/demo/table';
import { treeOptionsListApi } from '/@/api/demo/tree';
import { cloneDeep } from 'lodash-es';
import { useMessage } from '/@/hooks/web/useMessage';
import { useListPage } from '/@/hooks/system/useListPage';
const columns: BasicColumn[] = [
{
title: '输入框',
dataIndex: 'name',
editRow: true,
editComponentProps: {
prefix: '$',
},
width: 150,
},
{
title: '默认输入状态',
dataIndex: 'name7',
editRow: true,
width: 150,
},
{
title: '输入框校验',
dataIndex: 'name1',
editRow: true,
align: 'left',
//
editRule: true,
width: 150,
},
{
title: '输入框函数校验',
dataIndex: 'name2',
editRow: true,
align: 'right',
editRule: async (text) => {
if (text === '2') {
return '不能输入该值';
}
return '';
},
},
{
title: '数字输入框',
dataIndex: 'id',
editRow: true,
editRule: true,
editComponent: 'InputNumber',
width: 150,
},
{
title: '下拉框',
dataIndex: 'name3',
editRow: true,
editComponent: 'Select',
editComponentProps: {
options: [
{
label: 'Option1',
value: '1',
},
{
label: 'Option2',
value: '2',
},
{
label: 'Option3',
value: '3',
},
],
},
width: 200,
},
{
title: '远程下拉',
dataIndex: 'name4',
editRow: true,
editComponent: 'ApiSelect',
editComponentProps: {
api: optionsListApi,
resultField: 'list',
labelField: 'name',
valueField: 'id',
},
width: 200,
},
{
title: '远程下拉树',
dataIndex: 'name8',
editRow: true,
editComponent: 'ApiTreeSelect',
editRule: false,
editComponentProps: {
api: treeOptionsListApi,
resultField: 'list',
},
width: 200,
},
{
title: '日期选择',
dataIndex: 'date',
editRow: true,
editComponent: 'DatePicker',
editComponentProps: {
valueFormat: 'YYYY-MM-DD',
format: 'YYYY-MM-DD',
},
width: 150,
},
{
title: '时间选择',
dataIndex: 'time',
editRow: true,
editComponent: 'TimePicker',
editComponentProps: {
valueFormat: 'HH:mm',
format: 'HH:mm',
},
width: 100,
},
{
title: '勾选框',
dataIndex: 'name5',
editRow: true,
editComponent: 'Checkbox',
editValueMap: (value) => {
return value ? '是' : '否';
},
width: 100,
},
{
title: '开关',
dataIndex: 'name6',
editRow: true,
editComponent: 'Switch',
editValueMap: (value) => {
return value ? '开' : '关';
},
width: 100,
},
];
export default defineComponent({
components: { BasicTable, TableAction },
setup() {
const { createMessage: msg } = useMessage();
const currentEditKeyRef = ref('');
const { tableContext } = useListPage({
designScope: 'basic-table-demo',
tableProps: {
title: '可编辑行示例',
titleHelpMessage: ['本例中修改[数字输入框]这一列时,同一行的[远程下拉]列的当前编辑数据也会同步发生改变'],
api: demoListApi,
columns: columns,
showIndexColumn: false,
showTableSetting: true,
tableSetting: { fullScreen: true },
actionColumn: {
width: 160,
title: 'Action',
dataIndex: 'action',
slots: { customRender: 'action' },
},
useSearchForm: false,
},
});
//table
const [registerTable] = tableContext;
function handleEdit(record: EditRecordRow) {
currentEditKeyRef.value = record.key;
record.onEdit?.(true);
}
function handleCancel(record: EditRecordRow) {
currentEditKeyRef.value = '';
record.onEdit?.(false, false);
}
async function handleSave(record: EditRecordRow) {
//
msg.loading({ content: '正在保存...', duration: 0, key: 'saving' });
const valid = await record.onValid?.();
if (valid) {
try {
const data = cloneDeep(record.editValueRefs);
console.log(data);
//TODO
// ...
//
const pass = await record.onEdit?.(false, true);
if (pass) {
currentEditKeyRef.value = '';
}
msg.success({ content: '数据已保存', key: 'saving' });
} catch (error) {
msg.error({ content: '保存失败', key: 'saving' });
}
} else {
msg.error({ content: '请填写正确的数据', key: 'saving' });
}
}
function createActions(record: EditRecordRow, column: BasicColumn): ActionItem[] {
if (!record.editable) {
return [
{
label: '编辑',
disabled: currentEditKeyRef.value ? currentEditKeyRef.value !== record.key : false,
onClick: handleEdit.bind(null, record),
},
];
}
return [
{
label: '保存',
onClick: handleSave.bind(null, record, column),
},
{
label: '取消',
popConfirm: {
title: '是否取消编辑',
confirm: handleCancel.bind(null, record, column),
},
},
];
}
function onEditChange({ column, value, record }) {
//
if (column.dataIndex === 'id') {
record.editValueRefs.name4.value = `${value}`;
}
console.log(column, value, record);
}
return {
registerTable,
handleEdit,
createActions,
onEditChange,
};
},
});
</script>

View File

@ -0,0 +1,119 @@
<template>
<PageWrapper
title="可展开表格"
content="不可与scroll共用。TableAction组件可配置stopButtonPropagation来阻止操作按钮的点击事件冒泡以便配合Table组件的expandRowByClick"
>
<BasicTable @register="registerTable">
<template #expandedRowRender="{ record }">
<span>No: {{ record.no }} </span>
</template>
<template #action="{ record }">
<TableAction
stopButtonPropagation
:actions="[
{
label: '删除',
icon: 'ic:outline-delete-outline',
onClick: handleDelete.bind(null, record),
},
]"
:dropDownActions="[
{
label: '启用',
popConfirm: {
title: '是否启用?',
confirm: handleOpen.bind(null, record),
},
},
]"
/>
</template>
</BasicTable>
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicTable, useTable, TableAction, BasicColumn } from '/@/components/Table';
import { PageWrapper } from '/@/components/Page';
import { demoListApi } from '/@/api/demo/table';
import { useListPage } from '/@/hooks/system/useListPage';
const columns: BasicColumn[] = [
{
title: 'ID',
dataIndex: 'id',
fixed: 'left',
width: 200,
},
{
title: '姓名',
dataIndex: 'name',
width: 150,
filters: [
{ text: 'Male', value: 'male' },
{ text: 'Female', value: 'female' },
],
},
{
title: '地址',
dataIndex: 'address',
width: 300,
},
{
title: '编号',
dataIndex: 'no',
width: 150,
sorter: true,
defaultHidden: true,
},
{
title: '开始时间',
width: 150,
sorter: true,
dataIndex: 'beginTime',
},
{
title: '结束时间',
width: 150,
sorter: true,
dataIndex: 'endTime',
},
];
export default defineComponent({
components: { BasicTable, TableAction, PageWrapper },
setup() {
const { tableContext } = useListPage({
designScope: 'basic-table-demo',
tableProps: {
api: demoListApi,
title: '可展开表格演示',
titleHelpMessage: ['已启用expandRowByClick', '已启用stopButtonPropagation'],
columns: columns,
rowKey: 'id',
canResize: false,
expandRowByClick: true,
actionColumn: {
width: 160,
title: 'Action',
dataIndex: 'action',
},
useSearchForm: false,
},
});
//table
const [registerTable] = tableContext;
function handleDelete(record: Recordable) {
console.log('点击了删除', record);
}
function handleOpen(record: Recordable) {
console.log('点击了启用', record);
}
return {
registerTable,
handleDelete,
handleOpen,
};
},
});
</script>

View File

@ -0,0 +1,131 @@
<template>
<div class="p-4">
<!--引用表格-->
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<template #tableTitle>
<a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> </a-button>
<j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls"></j-upload-button>
</template>
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" />
</template>
</BasicTable>
</div>
</template>
<script lang="ts" name="basic-table-demo" setup>
import { ActionItem, BasicColumn, BasicTable, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
import { defHttp } from '/@/utils/http/axios';
//
const columns: BasicColumn[] = [
{
title: '姓名',
dataIndex: 'name',
width: 170,
align: 'left',
resizable: true,
sorter: {
multiple: 1,
},
},
{
title: '关键词',
dataIndex: 'keyWord',
width: 130,
resizable: true,
},
{
title: '打卡时间',
dataIndex: 'punchTime',
width: 140,
resizable: true,
},
{
title: '工资',
dataIndex: 'salaryMoney',
width: 140,
resizable: true,
sorter: {
multiple: 2,
},
},
{
title: '奖金',
dataIndex: 'bonusMoney',
width: 140,
resizable: true,
},
{
title: '性别',
dataIndex: 'sex',
sorter: {
multiple: 3,
},
filters: [
{ text: '男', value: '1' },
{ text: '女', value: '2' },
],
customRender: ({ record }) => {
return record.sex ? (record.sex == '1' ? '男' : '女') : '';
},
width: 120,
resizable: true,
},
{
title: '生日',
dataIndex: 'birthday',
width: 120,
resizable: true,
},
{
title: '邮箱',
dataIndex: 'email',
width: 120,
resizable: true,
},
];
//ajaxapi
const demoListApi = (params) => {
return defHttp.get({ url: '/test/jeecgDemo/list', params });
};
//
const { tableContext, onExportXls, onImportXls } = useListPage({
designScope: 'basic-table-demo-filter',
tableProps: {
title: '表单搜索',
api: demoListApi,
columns: columns,
showActionColumn: false,
useSearchForm: false,
},
exportConfig: {
name: '示例列表',
url: '/test/jeecgDemo/exportXls',
},
importConfig: {
url: '/test/jeecgDemo/importExcel',
},
});
//table
const [registerTable, { reload }, { rowSelection, selectedRows, selectedRowKeys }] = tableContext;
/**
* 操作栏
*/
function getTableAction(record): ActionItem[] {
return [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
},
];
}
function handleEdit(record) {
console.log(record);
}
</script>
<style scoped></style>

View File

@ -0,0 +1,98 @@
<template>
<div class="p-4">
<BasicTable @register="registerTable">
<template #action="{ record }">
<TableAction
:actions="[
{
label: '删除',
icon: 'ic:outline-delete-outline',
onClick: handleDelete.bind(null, record),
},
]"
:dropDownActions="[
{
label: '启用',
popConfirm: {
title: '是否启用?',
confirm: handleOpen.bind(null, record),
},
},
]"
/>
</template>
</BasicTable>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicTable, useTable, BasicColumn, TableAction } from '/@/components/Table';
import { demoListApi } from '/@/api/demo/table';
import { useListPage } from '/@/hooks/system/useListPage';
const columns: BasicColumn[] = [
{
title: 'ID',
dataIndex: 'id',
fixed: 'left',
width: 280,
},
{
title: '姓名',
dataIndex: 'name',
width: 260,
},
{
title: '地址',
dataIndex: 'address',
},
{
title: '编号',
dataIndex: 'no',
width: 300,
},
{
title: '开始时间',
width: 200,
dataIndex: 'beginTime',
},
{
title: '结束时间',
dataIndex: 'endTime',
width: 200,
},
];
export default defineComponent({
components: { BasicTable, TableAction },
setup() {
const { tableContext } = useListPage({
tableProps: {
title: '固定头和列示例',
api: demoListApi,
columns: columns,
canResize: false,
scroll: { y: 200 },
actionColumn: {
width: 160,
title: 'Action',
dataIndex: 'action',
},
useSearchForm: false,
},
});
const [registerTable] = tableContext;
function handleDelete(record: Recordable) {
console.log('点击了删除', record);
}
function handleOpen(record: Recordable) {
console.log('点击了启用', record);
}
return {
registerTable,
handleDelete,
handleOpen,
};
},
});
</script>

View File

@ -0,0 +1,131 @@
<template>
<div class="p-4">
<BasicTable @register="registerTable" class="components-table-demo-nested">
<template #bodyCell="{ column }">
<template v-if="column.key === 'operation'">
<a>Publish</a>
</template>
</template>
<template #expandedRowRender>
<a-table :columns="innerColumns" :data-source="innerData" :pagination="false">
<template #bodyCell="{ column }">
<template v-if="column.dataIndex === 'state'">
<span>
<a-badge status="success" />
Finished
</span>
</template>
<template v-if="column.dataIndex === 'operation'">
<span class="table-operation">
<a>Pause</a>
<a>Stop</a>
<a-dropdown>
<template #overlay>
<a-menu>
<a-menu-item>Action 1</a-menu-item>
<a-menu-item>Action 2</a-menu-item>
</a-menu>
</template>
<a> More </a>
</a-dropdown>
</span>
</template>
</template>
</a-table>
</template>
</BasicTable>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicTable } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
const columns = [
{ title: 'Name', dataIndex: 'name', key: 'name' },
{ title: 'Platform', dataIndex: 'platform', key: 'platform' },
{ title: 'Version', dataIndex: 'version', key: 'version' },
{ title: 'Upgraded', dataIndex: 'upgradeNum', key: 'upgradeNum' },
{ title: 'Creator', dataIndex: 'creator', key: 'creator' },
{ title: 'Date', dataIndex: 'createdAt', key: 'createdAt' },
{ title: 'Action', key: 'operation' },
];
interface DataItem {
key: number;
name: string;
platform: string;
version: string;
upgradeNum: number;
creator: string;
createdAt: string;
}
const data: DataItem[] = [];
for (let i = 0; i < 3; ++i) {
data.push({
key: i,
name: 'Screem',
platform: 'iOS',
version: '10.3.4.5654',
upgradeNum: 500,
creator: 'Jack',
createdAt: '2014-12-24 23:12:00',
});
}
const innerColumns = [
{ title: 'Date', dataIndex: 'date', key: 'date' },
{ title: 'Name', dataIndex: 'name', key: 'name' },
{ title: 'Status', dataIndex: 'state', key: 'state' },
{ title: 'Upgrade Status', dataIndex: 'upgradeNum', key: 'upgradeNum' },
{
title: 'Action',
dataIndex: 'operation',
key: 'operation',
},
];
interface innerDataItem {
key: number;
date: string;
name: string;
upgradeNum: string;
}
const innerData: innerDataItem[] = [];
for (let i = 0; i < 3; ++i) {
innerData.push({
key: i,
date: '2014-12-24 23:12:00',
name: 'This is production name',
upgradeNum: 'Upgraded: 56',
});
}
export default defineComponent({
components: { BasicTable },
setup() {
//
const { tableContext } = useListPage({
tableProps: {
title: '内嵌表格',
dataSource: data,
columns: columns,
showActionColumn: false,
rowKey: 'key',
useSearchForm: false,
},
});
//table
const [registerTable] = tableContext;
return {
data,
columns,
innerColumns,
innerData,
registerTable,
};
},
});
</script>

View File

@ -0,0 +1,70 @@
<template>
<div class="p-4">
<BasicTable @register="registerTable" />
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicColumn, BasicTable, useTable } from '/@/components/Table';
import { demoListApi } from '/@/api/demo/table';
//
export default defineComponent({
components: { BasicTable },
setup() {
const [registerTable] = useTable({
title: '分组表头示例',
api: demoListApi,
columns: getMergeHeaderColumns(),
bordered: true,
useSearchForm: false,
});
function getMergeHeaderColumns(): BasicColumn[] {
return [
{
title: 'ID',
dataIndex: 'id',
width: 300,
},
{
title: '姓名',
dataIndex: 'name',
width: 300,
},
{
title: '地址',
width: 120,
children: [
{
title: '地址',
dataIndex: 'address',
key: 'address',
width: 200,
},
{
title: '编号',
dataIndex: 'no',
key: 'no',
},
],
},
{
title: '开始时间',
dataIndex: 'beginTime',
width: 200,
},
{
title: '结束时间',
dataIndex: 'endTime',
width: 200,
},
];
}
return {
registerTable,
};
},
});
</script>

View File

@ -0,0 +1,144 @@
<template>
<div class="p-4">
<!--引用表格-->
<BasicTable @register="registerTable">
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" />
</template>
</BasicTable>
</div>
</template>
<script lang="ts" name="basic-table-demo" setup>
import { ActionItem, BasicColumn, BasicTable, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
//
const columns: BasicColumn[] = [
{
title: '名称',
dataIndex: 'name',
customCell: (record, index, column) => ({
colSpan: index < 4 ? 1 : 5,
}),
customRender: ({ text, record, index, column }) => {
return index < 4 ? text : `${record.name}/${record.age}/${record.address}/${record.phone}`;
},
},
{
title: '年龄',
dataIndex: 'age',
customCell: (record, index, column) => {
if (index == 4) {
return { colSpan: 0 };
}
},
},
{
title: '家庭住址',
dataIndex: 'address',
customCell: (record, index, column) => {
if (index == 4) {
return { colSpan: 0 };
}
},
},
{
title: '联系电话',
colSpan: 2,
dataIndex: 'tel',
customCell: (record, index, column) => {
if (index === 2) {
return { rowSpan: 2 };
}
if (index === 3) {
return { rowSpan: 0 };
}
if (index === 4) {
return { colSpan: 0 };
}
},
},
{
title: 'Phone',
colSpan: 0,
dataIndex: 'phone',
customCell: (record, index, column) => {
if (index === 4) {
return { colSpan: 0 };
}
},
},
];
//
const { tableContext } = useListPage({
designScope: 'basic-table-demo',
tableProps: {
title: '合并行列',
dataSource: [
{
key: '1',
name: '尹嘉乐',
age: 32,
tel: '0319-5972018',
phone: 17600080009,
address: '北京市昌平区',
},
{
key: '2',
name: '龙佳钰',
tel: '0319-5972018',
phone: 17600060007,
age: 42,
address: '北京市海淀区',
},
{
key: '3',
name: '贺泽惠',
age: 32,
tel: '0319-5972018',
phone: 17600040005,
address: '北京市门头沟区',
},
{
key: '4',
name: '沈勇',
age: 18,
tel: '0319-5972018',
phone: 17600010003,
address: '北京市朝阳区',
},
{
key: '5',
name: '白佳毅',
age: 18,
tel: '0319-5972018',
phone: 17600010002,
address: '北京市丰台区',
},
],
columns: columns,
showActionColumn: false,
useSearchForm: false,
},
});
//table
const [registerTable] = tableContext;
/**
* 操作栏
*/
function getTableAction(record): ActionItem[] {
return [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
},
];
}
function handleEdit(record) {
console.log(record);
}
</script>
<style scoped></style>

View File

@ -0,0 +1,80 @@
<template>
<div class="p-4">
<!--引用表格-->
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" />
</template>
</BasicTable>
</div>
</template>
<script lang="ts" name="basic-table-demo" setup>
import { BasicColumn, BasicTable, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
//
const columns: BasicColumn[] = [
{
title: '姓名',
dataIndex: 'name',
key: 'name',
resizable: true,
},
{
title: '年龄',
dataIndex: 'age',
key: 'age',
},
{
title: '住址',
dataIndex: 'address',
key: 'address',
},
];
//
const { tableContext } = useListPage({
designScope: 'basic-table-demo',
tableProps: {
title: '可选择表格',
dataSource: [
{
id: '1',
name: '胡歌',
age: 32,
address: '朝阳区林萃路1号',
},
{
id: '2',
name: '刘诗诗',
age: 32,
address: '昌平区白沙路1号',
},
],
columns: columns,
rowSelection: { type: 'checkbox' }, // checkbox radio
useSearchForm: false,
},
});
//table
const [registerTable, { reload }, { rowSelection, selectedRows, selectedRowKeys }] = tableContext;
/**
* 操作栏
*/
function getTableAction(record): ActionItem[] {
return [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
},
];
}
function handleEdit(record) {
console.log(record);
console.log(selectedRows.value);
console.log(selectedRowKeys.value);
}
</script>
<style scoped></style>

View File

@ -0,0 +1,124 @@
<template>
<div class="p-4">
<BasicTable @register="register">
<template #toolbar>
<a-button type="primary" @click="expandAll"></a-button>
<a-button type="primary" @click="collapseAll"></a-button>
</template>
</BasicTable>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicColumn, BasicTable } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
const columns: BasicColumn[] = [
{
title: 'ID',
dataIndex: 'id',
fixed: 'left',
width: 200,
},
{
title: '姓名',
dataIndex: 'name',
width: 150,
filters: [
{ text: 'Male', value: 'male' },
{ text: 'Female', value: 'female' },
],
},
{
title: '地址',
dataIndex: 'address',
width: 300,
},
{
title: '编号',
dataIndex: 'no',
width: 150,
sorter: true,
defaultHidden: true,
},
{
title: '开始时间',
width: 150,
sorter: true,
dataIndex: 'beginTime',
},
{
title: '结束时间',
width: 150,
sorter: true,
dataIndex: 'endTime',
},
];
export default defineComponent({
components: { BasicTable },
setup() {
const { tableContext } = useListPage({
tableProps: {
title: '树形表格',
isTreeTable: true,
rowSelection: {
type: 'checkbox',
getCheckboxProps(record: Recordable) {
// Demo: id0
if (record.id === '0') {
return { disabled: true };
} else {
return { disabled: false };
}
},
},
columns: columns,
dataSource: getTreeTableData(),
rowKey: 'id',
useSearchForm: false,
},
});
//table
const [register, { expandAll, collapseAll }] = tableContext;
function getTreeTableData() {
const data: any = (() => {
const arr: any = [];
for (let index = 0; index < 40; index++) {
arr.push({
id: `${index}`,
name: 'John Brown',
age: `1${index}`,
no: `${index + 10}`,
address: 'New York No. 1 Lake ParkNew York No. 1 Lake Park',
beginTime: new Date().toLocaleString(),
endTime: new Date().toLocaleString(),
children: [
{
id: `l2-${index}`,
name: 'John Brown',
age: `1${index}`,
no: `${index + 10}`,
address: 'New York No. 1 Lake ParkNew York No. 1 Lake Park',
beginTime: new Date().toLocaleString(),
endTime: new Date().toLocaleString(),
},
{
id: `l3-${index}`,
name: 'John Mary',
age: `1${index}`,
no: `${index + 10}`,
address: 'New York No. 1 Lake ParkNew York No. 1 Lake Park',
beginTime: new Date().toLocaleString(),
endTime: new Date().toLocaleString(),
},
],
});
}
return arr;
})();
return data;
}
return { register, expandAll, collapseAll };
},
});
</script>

View File

@ -0,0 +1,15 @@
export { default as AuthColumnDemo } from './AuthColumnDemo.vue';
export { default as BasicTableBorder } from './BasicTableBorder.vue';
export { default as BasicTableDemo } from './BasicTableDemo.vue';
export { default as BasicTableDemoAjax } from './BasicTableDemoAjax.vue';
export { default as CustomerCellDemo } from './CustomerCellDemo.vue';
export { default as EditCellTableDemo } from './EditCellTableDemo.vue';
export { default as EditRowTableDemo } from './EditRowTableDemo.vue';
export { default as ExpandTableDemo } from './ExpandTableDemo.vue';
export { default as ExportTableDemo } from './ExportTableDemo.vue';
export { default as FixedHeaderColumn } from './FixedHeaderColumn.vue';
export { default as InnerTableDemo } from './InnerTableDemo.vue';
export { default as MergeHeaderDemo } from './MergeHeaderDemo.vue';
export { default as MergeTableDemo } from './MergeTableDemo.vue';
export { default as SelectTableDemo } from './SelectTableDemo.vue';
export { default as TreeTableDemo } from './TreeTableDemo.vue';

View File

@ -0,0 +1,87 @@
<template>
<div class="p-4">
<a-card :bordered="false" style="height: 100%">
<a-tabs v-model:activeKey="activeKey" @change="tabChange">
<a-tab-pane :key="item.key" :tab="item.label" v-for="item in compList" />
</a-tabs>
<component :is="currentComponent" />
</a-card>
</div>
</template>
<script lang="ts">
import { defineComponent, ref, computed } from 'vue';
import {
AuthColumnDemo,
BasicTableBorder,
BasicTableDemo,
BasicTableDemoAjax,
CustomerCellDemo,
EditCellTableDemo,
EditRowTableDemo,
ExpandTableDemo,
ExportTableDemo,
FixedHeaderColumn,
InnerTableDemo,
MergeHeaderDemo,
MergeTableDemo,
SelectTableDemo,
TreeTableDemo,
} from './index';
export default defineComponent({
name: 'document-table-demo',
components: {
AuthColumnDemo,
BasicTableBorder,
BasicTableDemo,
BasicTableDemoAjax,
CustomerCellDemo,
EditCellTableDemo,
EditRowTableDemo,
ExpandTableDemo,
ExportTableDemo,
FixedHeaderColumn,
InnerTableDemo,
MergeHeaderDemo,
MergeTableDemo,
SelectTableDemo,
TreeTableDemo,
},
setup() {
//key
const activeKey = ref('BasicTableDemo');
//
const compList = ref([
{ key: 'BasicTableDemo', label: '基础静态表格' },
{ key: 'BasicTableDemoAjax', label: '常规AJAX表格' },
{ key: 'BasicTableBorder', label: '边框表格' },
{ key: 'CustomerCellDemo', label: '自定义列内容' },
{ key: 'EditCellTableDemo', label: '可编辑单元格' },
{ key: 'EditRowTableDemo', label: '可编辑行' },
{ key: 'ExpandTableDemo', label: '可展开表格' },
{ key: 'ExportTableDemo', label: '导入导出' },
{ key: 'FixedHeaderColumn', label: '固定头和列示例' },
{ key: 'InnerTableDemo', label: '内嵌表格' },
{ key: 'MergeHeaderDemo', label: '分组表头示例' },
{ key: 'MergeTableDemo', label: '合并行列' },
{ key: 'SelectTableDemo', label: '可选择表格' },
{ key: 'TreeTableDemo', label: '树形表格' },
{ key: 'AuthColumnDemo', label: '权限列设置' },
]);
//
const currentComponent = computed(() => {
return activeKey.value;
});
//使componenttab
function tabChange(key) {
activeKey.value = key;
}
return {
activeKey,
currentComponent,
tabChange,
compList,
};
},
});
</script>