feat: allowClear to clearable

This commit is contained in:
xingyu4j
2025-10-16 18:05:39 +08:00
parent dd1528d45a
commit e358c85c15
16 changed files with 107 additions and 100 deletions

View File

@@ -5,6 +5,7 @@
## 组件列表
### 1. ImageUpload - 图片上传组件
- **文件**: `image-upload.vue`
- **功能**: 专门用于图片上传的组件,支持图片预览
- **特性**:
@@ -16,6 +17,7 @@
- 支持进度显示
### 2. FileUpload - 文件上传组件
- **文件**: `file-upload.vue`
- **功能**: 通用文件上传组件
- **特性**:
@@ -28,6 +30,7 @@
- 支持返回文本内容(用于配置文件等)
### 3. InputUpload - 输入框上传组件
- **文件**: `input-upload.vue`
- **功能**: 结合输入框和文件上传的组件
- **特性**:
@@ -94,7 +97,7 @@ const configContent = ref('');
input-type="textarea"
:file-upload-props="{
accept: ['json', 'yaml', 'yml'],
maxSize: 1
maxSize: 1,
}"
/>
</template>
@@ -104,39 +107,39 @@ const configContent = ref('');
### 通用 Props (FileUploadProps)
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| modelValue/value | `string \| string[]` | - | v-model 绑定值 |
| accept | `string[]` | `[]` | 接受的文件类型 |
| maxSize | `number` | `2` | 文件最大大小MB |
| maxNumber | `number` | `1` | 最大文件数量 |
| multiple | `boolean` | `false` | 是否支持多选 |
| disabled | `boolean` | `false` | 是否禁用 |
| drag | `boolean` | `false` | 是否支持拖拽上传 |
| directory | `string` | - | 上传目录 |
| api | `Function` | - | 自定义上传 API |
| showDescription | `boolean` | - | 是否显示描述文本 |
| 属性 | 类型 | 默认值 | 说明 |
| ---------------- | -------------------- | ------- | ------------------ |
| modelValue/value | `string \| string[]` | - | v-model 绑定值 |
| accept | `string[]` | `[]` | 接受的文件类型 |
| maxSize | `number` | `2` | 文件最大大小MB |
| maxNumber | `number` | `1` | 最大文件数量 |
| multiple | `boolean` | `false` | 是否支持多选 |
| disabled | `boolean` | `false` | 是否禁用 |
| drag | `boolean` | `false` | 是否支持拖拽上传 |
| directory | `string` | - | 上传目录 |
| api | `Function` | - | 自定义上传 API |
| showDescription | `boolean` | - | 是否显示描述文本 |
### ImageUpload 特有 Props
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| --- | --- | --- | --- |
| listType | `string` | `'picture-card'` | 列表类型 |
| accept | `string[]` | `['jpg', 'jpeg', 'png', 'gif', 'webp']` | 接受的图片类型 |
| showDescription | `boolean` | `true` | 是否显示描述文本 |
### InputUpload 特有 Props
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| inputType | `'input' \| 'textarea'` | `'input'` | 输入框类型 |
| inputProps | `InputProps` | - | 输入框属性 |
| fileUploadProps | `FileUploadProps` | - | 文件上传组件属性 |
| 属性 | 类型 | 默认值 | 说明 |
| --------------- | ----------------------- | --------- | ---------------- |
| inputType | `'input' \| 'textarea'` | `'input'` | 输入框类型 |
| inputProps | `InputProps` | - | 输入框属性 |
| fileUploadProps | `FileUploadProps` | - | 文件上传组件属性 |
## Events
| 事件名 | 参数 | 说明 |
|--------|------|------|
| --- | --- | --- |
| update:value | `value: string \| string[]` | 值更新事件 |
| update:modelValue | `value: string \| string[]` | v-model 更新事件 |
| change | `value: string \| string[]` | 值变化事件 |
@@ -147,6 +150,7 @@ const configContent = ref('');
## 辅助工具
### useUpload
- **文件**: `use-upload.ts`
- **功能**: 提供上传相关的工具函数
- **主要方法**:
@@ -154,6 +158,7 @@ const configContent = ref('');
- `getUploadUrl`: 获取上传 URL
### useUploadType
- **功能**: 处理上传类型相关的逻辑
- **主要方法**:
- `getStringAccept`: 获取 accept 字符串
@@ -162,7 +167,7 @@ const configContent = ref('');
## 技术栈
- **UI 框架**: Naive UI
- **核心组件**:
- **核心组件**:
- NUpload
- NImage
- NImageGroup
@@ -170,7 +175,7 @@ const configContent = ref('');
- NButton
- NGrid
- NInput
- **工具库**:
- **工具库**:
- @vueuse/core
- @vben/utils
@@ -189,50 +194,55 @@ const configContent = ref('');
从 Ant Design Vue 迁移到 Naive UI 的主要变化:
1. **组件导入**:
```typescript
// 旧
import { Upload } from 'ant-design-vue';
// 新
import { NUpload } from 'naive-ui';
```
2. **文件列表类型**:
```typescript
// 旧
import type { UploadFile } from 'ant-design-vue';
// 新
import type { UploadFileInfo } from 'naive-ui';
```
3. **状态值**:
```typescript
// 旧
status: 'done'
status: 'done';
// 新
status: 'finished'
status: 'finished';
```
4. **事件回调**:
```typescript
// 旧
@remove="handleRemove"
function handleRemove(file: UploadFile) { }
// 新
@remove="handleRemove"
function handleRemove(options: { file: UploadFileInfo; fileList: UploadFileInfo[] }) { }
```
5. **自定义上传**:
```typescript
// 旧
customRequest(info: UploadRequestOption) {
info.onSuccess!(res);
}
// 新
customRequest(options: UploadCustomRequestOptions) {
options.onFinish();
@@ -242,9 +252,9 @@ const configContent = ref('');
## 更新日志
### v1.0.0 (2025-01-16)
- ✅ 将所有上传组件从 Ant Design Vue 重构为 Naive UI
- ✅ 保持原有功能和 API 兼容性
- ✅ 优化代码结构和类型定义
- ✅ 修复所有 linter 错误
- ✅ 添加完整的文档说明

View File

@@ -21,7 +21,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
label: '用户编号',
component: 'Input',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '请输入用户编号',
},
},
@@ -31,7 +31,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
component: 'Select',
componentProps: {
options: getDictOptions(DICT_TYPE.USER_TYPE, 'number'),
allowClear: true,
clearable: true,
placeholder: '请选择用户类型',
},
},
@@ -40,7 +40,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
label: '应用名',
component: 'Input',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '请输入应用名',
},
},
@@ -50,7 +50,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
component: 'DatePicker',
componentProps: {
...getRangePickerDefaultProps(),
allowClear: true,
clearable: true,
},
},
{
@@ -58,7 +58,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
label: '执行时长',
component: 'Input',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '请输入执行时长',
},
},
@@ -67,7 +67,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
label: '结果码',
component: 'Input',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '请输入结果码',
},
},

View File

@@ -21,7 +21,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
label: '用户编号',
component: 'Input',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '请输入用户编号',
},
},
@@ -31,7 +31,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
component: 'Select',
componentProps: {
options: getDictOptions(DICT_TYPE.USER_TYPE, 'number'),
allowClear: true,
clearable: true,
placeholder: '请选择用户类型',
},
},
@@ -40,7 +40,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
label: '应用名',
component: 'Input',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '请输入应用名',
},
},
@@ -50,7 +50,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
component: 'DatePicker',
componentProps: {
...getRangePickerDefaultProps(),
allowClear: true,
clearable: true,
},
},
{
@@ -62,7 +62,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
DICT_TYPE.INFRA_API_ERROR_LOG_PROCESS_STATUS,
'number',
),
allowClear: true,
clearable: true,
placeholder: '请选择处理状态',
},
defaultValue: InfraApiErrorLogProcessStatusEnum.INIT,

View File

@@ -42,7 +42,7 @@ export function useImportTableFormSchema(): VbenFormSchema[] {
label: '表名称',
component: 'Input',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '请输入表名称',
},
},
@@ -51,7 +51,7 @@ export function useImportTableFormSchema(): VbenFormSchema[] {
label: '表描述',
component: 'Input',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '请输入表描述',
},
},
@@ -163,7 +163,7 @@ export function useGenerationInfoBaseFormSchema(): VbenFormSchema[] {
help: '分配到指定菜单下,例如 系统管理',
component: 'ApiTreeSelect',
componentProps: {
allowClear: true,
clearable: true,
api: async () => {
const data = await getMenuList();
data.unshift({
@@ -257,7 +257,7 @@ export function useGenerationInfoTreeFormSchema(
help: '树显示的父编码字段名,例如 parent_Id',
componentProps: {
class: 'w-full',
allowClear: true,
clearable: true,
placeholder: '请选择',
options: columns.map((column) => ({
label: column.columnName,
@@ -273,7 +273,7 @@ export function useGenerationInfoTreeFormSchema(
help: '树节点显示的名称字段,一般是 name',
componentProps: {
class: 'w-full',
allowClear: true,
clearable: true,
placeholder: '请选择名称字段',
options: columns.map((column) => ({
label: column.columnName,
@@ -309,7 +309,7 @@ export function useGenerationInfoSubTableFormSchema(
help: '关联主表(父表)的表名, 如system_user',
componentProps: {
class: 'w-full',
allowClear: true,
clearable: true,
placeholder: '请选择',
options: tables.map((table) => ({
label: `${table.tableName}${table.tableComment}`,
@@ -325,7 +325,7 @@ export function useGenerationInfoSubTableFormSchema(
help: '子表关联的字段, 如user_id',
componentProps: {
class: 'w-full',
allowClear: true,
clearable: true,
placeholder: '请选择',
options: columns.map((column) => ({
label: `${column.columnName}:${column.columnComment}`,
@@ -341,7 +341,7 @@ export function useGenerationInfoSubTableFormSchema(
help: '主表与子表的关联关系',
componentProps: {
class: 'w-full',
allowClear: true,
clearable: true,
placeholder: '请选择',
options: [
{
@@ -367,7 +367,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
label: '表名称',
component: 'Input',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '请输入表名称',
},
},
@@ -376,7 +376,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
label: '表描述',
component: 'Input',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '请输入表描述',
},
},
@@ -386,7 +386,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
component: 'DatePicker',
componentProps: {
...getRangePickerDefaultProps(),
allowClear: true,
clearable: true,
},
},
];

View File

@@ -86,7 +86,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
component: 'Input',
componentProps: {
placeholder: '请输入参数名称',
allowClear: true,
clearable: true,
},
},
{
@@ -95,7 +95,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
component: 'Input',
componentProps: {
placeholder: '请输入参数键名',
allowClear: true,
clearable: true,
},
},
{
@@ -105,7 +105,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
componentProps: {
options: getDictOptions(DICT_TYPE.INFRA_CONFIG_TYPE, 'number'),
placeholder: '请选择系统内置',
allowClear: true,
clearable: true,
},
},
{
@@ -114,7 +114,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
component: 'DatePicker',
componentProps: {
...getRangePickerDefaultProps(),
allowClear: true,
clearable: true,
},
},
];

View File

@@ -71,7 +71,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
label: '名字',
component: 'Input',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '请输入名字',
},
},
@@ -80,7 +80,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
label: '性别',
component: 'Select',
componentProps: {
allowClear: true,
clearable: true,
options: getDictOptions(DICT_TYPE.SYSTEM_USER_SEX, 'number'),
placeholder: '请选择性别',
},
@@ -91,7 +91,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
component: 'DatePicker',
componentProps: {
...getRangePickerDefaultProps(),
allowClear: true,
clearable: true,
},
},
];

View File

@@ -23,7 +23,7 @@ export function useFormSchema(): VbenFormSchema[] {
label: '上级示例分类',
component: 'ApiTreeSelect',
componentProps: {
allowClear: true,
clearable: true,
api: async () => {
const data = await getDemo02CategoryList({});
data.unshift({
@@ -60,7 +60,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
label: '名字',
component: 'Input',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '请输入名字',
},
},
@@ -69,7 +69,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
label: '父级编号',
component: 'Input',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '请输入父级编号',
},
},
@@ -79,7 +79,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
component: 'DatePicker',
componentProps: {
...getRangePickerDefaultProps(),
allowClear: true,
clearable: true,
},
},
];

View File

@@ -66,7 +66,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
label: '名字',
component: 'Input',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '请输入名字',
},
},
@@ -75,7 +75,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
label: '性别',
component: 'Select',
componentProps: {
allowClear: true,
clearable: true,
options: getDictOptions(DICT_TYPE.SYSTEM_USER_SEX, 'number'),
placeholder: '请选择性别',
},
@@ -85,7 +85,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
label: '简介',
component: 'Input',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '请输入简介',
},
},
@@ -95,7 +95,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
component: 'DatePicker',
componentProps: {
...getRangePickerDefaultProps(),
allowClear: true,
clearable: true,
},
},
];
@@ -192,7 +192,7 @@ export function useDemo03CourseGridFormSchema(): VbenFormSchema[] {
label: '学生编号',
component: 'Input',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '请输入学生编号',
},
},
@@ -201,7 +201,7 @@ export function useDemo03CourseGridFormSchema(): VbenFormSchema[] {
label: '名字',
component: 'Input',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '请输入名字',
},
},
@@ -210,7 +210,7 @@ export function useDemo03CourseGridFormSchema(): VbenFormSchema[] {
label: '分数',
component: 'Input',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '请输入分数',
},
},
@@ -220,7 +220,7 @@ export function useDemo03CourseGridFormSchema(): VbenFormSchema[] {
component: 'DatePicker',
componentProps: {
...getRangePickerDefaultProps(),
allowClear: true,
clearable: true,
},
},
];
@@ -307,7 +307,7 @@ export function useDemo03GradeGridFormSchema(): VbenFormSchema[] {
label: '学生编号',
component: 'Input',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '请输入学生编号',
},
},
@@ -316,7 +316,7 @@ export function useDemo03GradeGridFormSchema(): VbenFormSchema[] {
label: '名字',
component: 'Input',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '请输入名字',
},
},
@@ -325,7 +325,7 @@ export function useDemo03GradeGridFormSchema(): VbenFormSchema[] {
label: '班主任',
component: 'Input',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '请输入班主任',
},
},
@@ -335,7 +335,7 @@ export function useDemo03GradeGridFormSchema(): VbenFormSchema[] {
component: 'DatePicker',
componentProps: {
...getRangePickerDefaultProps(),
allowClear: true,
clearable: true,
},
},
];

View File

@@ -5,9 +5,8 @@ import { computed, ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { message } from '#/adapter/naive';
import { useVbenForm } from '#/adapter/form';
import { message } from '#/adapter/naive';
import {
createDemo03Grade,
getDemo03Grade,

View File

@@ -8,7 +8,6 @@ import { confirm, useVbenModal } from '@vben/common-ui';
import { isEmpty } from '@vben/utils';
import { message } from '#/adapter/naive';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import {
deleteDemo03Grade,
@@ -176,7 +175,7 @@ watch(
{
label: $t('common.edit'),
type: 'primary',
text: true,
text: true,
icon: ACTION_ICON.EDIT,
auth: ['infra:demo03-student:update'],
onClick: handleEdit.bind(null, row),
@@ -185,7 +184,7 @@ watch(
label: $t('common.delete'),
danger: true,
type: 'primary',
text: true,
text: true,
icon: ACTION_ICON.DELETE,
auth: ['infra:demo03-student:delete'],
popConfirm: {

View File

@@ -5,9 +5,8 @@ import { computed, ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { message } from '#/adapter/naive';
import { useVbenForm } from '#/adapter/form';
import { message } from '#/adapter/naive';
import {
createDemo03Student,
getDemo03Student,

View File

@@ -66,7 +66,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
label: '名字',
component: 'Input',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '请输入名字',
},
},
@@ -75,7 +75,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
label: '性别',
component: 'Select',
componentProps: {
allowClear: true,
clearable: true,
options: getDictOptions(DICT_TYPE.SYSTEM_USER_SEX, 'number'),
placeholder: '请选择性别',
},
@@ -85,7 +85,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
label: '简介',
component: 'Input',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '请输入简介',
},
},
@@ -95,7 +95,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
component: 'DatePicker',
componentProps: {
...getRangePickerDefaultProps(),
allowClear: true,
clearable: true,
},
},
];

View File

@@ -66,7 +66,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
label: '名字',
component: 'Input',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '请输入名字',
},
},
@@ -75,7 +75,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
label: '性别',
component: 'Select',
componentProps: {
allowClear: true,
clearable: true,
options: getDictOptions(DICT_TYPE.SYSTEM_USER_SEX, 'number'),
placeholder: '请选择性别',
},
@@ -85,7 +85,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
label: '简介',
component: 'Input',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '请输入简介',
},
},
@@ -95,7 +95,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
component: 'DatePicker',
componentProps: {
...getRangePickerDefaultProps(),
allowClear: true,
clearable: true,
},
},
];

View File

@@ -256,7 +256,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
component: 'Input',
componentProps: {
placeholder: '请输入配置名',
allowClear: true,
clearable: true,
},
},
{
@@ -266,7 +266,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
componentProps: {
options: getDictOptions(DICT_TYPE.INFRA_FILE_STORAGE, 'number'),
placeholder: '请选择存储器',
allowClear: true,
clearable: true,
},
},
{
@@ -275,7 +275,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
component: 'DatePicker',
componentProps: {
...getRangePickerDefaultProps(),
allowClear: true,
clearable: true,
},
},
];

View File

@@ -104,7 +104,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
label: '任务名称',
component: 'Input',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '请输入任务名称',
},
},
@@ -114,7 +114,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
component: 'Select',
componentProps: {
options: getDictOptions(DICT_TYPE.INFRA_JOB_STATUS, 'number'),
allowClear: true,
clearable: true,
placeholder: '请选择任务状态',
},
},
@@ -123,7 +123,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
label: '处理器的名字',
component: 'Input',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '请输入处理器的名字',
},
},

View File

@@ -21,7 +21,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
label: '处理器的名字',
component: 'Input',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '请输入处理器的名字',
},
},
@@ -30,7 +30,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
label: '开始执行时间',
component: 'DatePicker',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '选择开始执行时间',
valueFormat: 'YYYY-MM-DD HH:mm:ss',
showTime: {
@@ -44,7 +44,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
label: '结束执行时间',
component: 'DatePicker',
componentProps: {
allowClear: true,
clearable: true,
placeholder: '选择结束执行时间',
valueFormat: 'YYYY-MM-DD HH:mm:ss',
showTime: {
@@ -59,7 +59,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
component: 'Select',
componentProps: {
options: getDictOptions(DICT_TYPE.INFRA_JOB_LOG_STATUS, 'number'),
allowClear: true,
clearable: true,
placeholder: '请选择任务状态',
},
},