tree-upload-vue3 1.1.10 → 1.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -5
- package/dist/components/SchemaTable.vue.d.ts +1 -0
- package/dist/tree-upload-vue3.css +1 -1
- package/dist/tree-upload-vue3.es.js +594 -516
- package/dist/tree-upload-vue3.umd.js +1 -1
- package/dist/types/index.d.ts +16 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -37,7 +37,7 @@ npm install tree-upload-vue3 element-plus @element-plus/icons-vue file-preview-v
|
|
|
37
37
|
<TreeUpload
|
|
38
38
|
ref="treeUploadRef"
|
|
39
39
|
:schema="mySchema"
|
|
40
|
-
mode="
|
|
40
|
+
mode="view"
|
|
41
41
|
@upload-before="handleBeforeUpload"
|
|
42
42
|
@upload-success="handleUploadSuccess"
|
|
43
43
|
/>
|
|
@@ -51,9 +51,9 @@ import 'tree-upload-vue3/dist/tree-upload-vue3.css'; // 引入样式
|
|
|
51
51
|
|
|
52
52
|
const treeUploadRef = ref();
|
|
53
53
|
|
|
54
|
-
const handleBeforeUpload = ({ file, context }) => {
|
|
54
|
+
const handleBeforeUpload = ({ file, context, currentNode }) => {
|
|
55
55
|
console.log('准备上传:', file.name);
|
|
56
|
-
console.log('当前选中节点:', context.variables.currentNode);
|
|
56
|
+
console.log('当前选中节点:', currentNode || context.variables.currentNode);
|
|
57
57
|
};
|
|
58
58
|
|
|
59
59
|
const handleUploadSuccess = (response) => {
|
|
@@ -69,9 +69,18 @@ const mySchema = reactive<TreeUploadSchema>({
|
|
|
69
69
|
{
|
|
70
70
|
id: '1',
|
|
71
71
|
label: '必填文档',
|
|
72
|
+
mode: 'edit',
|
|
72
73
|
required: true,
|
|
73
74
|
minCount: 1,
|
|
74
75
|
accept: '.pdf',
|
|
76
|
+
beforeUpload: ({ file }) => {
|
|
77
|
+
return !file.name.startsWith('tmp_');
|
|
78
|
+
},
|
|
79
|
+
meta: {
|
|
80
|
+
upload: {
|
|
81
|
+
beforeUpload: ({ file }) => file.name.endsWith('.pdf')
|
|
82
|
+
}
|
|
83
|
+
},
|
|
75
84
|
children: []
|
|
76
85
|
}
|
|
77
86
|
]
|
|
@@ -85,6 +94,17 @@ const mySchema = reactive<TreeUploadSchema>({
|
|
|
85
94
|
enabled: true,
|
|
86
95
|
action: 'https://api.example.com/upload',
|
|
87
96
|
multiple: true,
|
|
97
|
+
beforeUpload: ({ file }) => {
|
|
98
|
+
return file.size < 20 * 1024 * 1024;
|
|
99
|
+
},
|
|
100
|
+
// 可选:转换接口响应为组件所需的 FileItem 格式
|
|
101
|
+
transformResponse: (response) => {
|
|
102
|
+
return {
|
|
103
|
+
id: response.data.id,
|
|
104
|
+
name: response.data.filename,
|
|
105
|
+
url: response.data.url
|
|
106
|
+
};
|
|
107
|
+
},
|
|
88
108
|
ui: {
|
|
89
109
|
showTip: true // 自动显示 "支持 .pdf (最少 1 个)" 等提示
|
|
90
110
|
}
|
|
@@ -110,13 +130,13 @@ const mySchema = reactive<TreeUploadSchema>({
|
|
|
110
130
|
| 属性名 | 类型 | 默认值 | 说明 |
|
|
111
131
|
| --- | --- | --- | --- |
|
|
112
132
|
| `schema` | `TreeUploadSchema` | **必填** | 组件的核心配置对象 |
|
|
113
|
-
| `mode` | `'view' \| 'edit'` | `'edit'` |
|
|
133
|
+
| `mode` | `'view' \| 'edit'` | `'edit'` | 全局视图模式。可被节点级 `mode` 覆盖 |
|
|
114
134
|
|
|
115
135
|
### Events
|
|
116
136
|
|
|
117
137
|
| 事件名 | 参数 | 说明 |
|
|
118
138
|
| --- | --- | --- |
|
|
119
|
-
| `upload-before` | `{ file: File, context: SchemaContext }` | 上传前触发,包含文件对象和当前上下文(如选中节点) |
|
|
139
|
+
| `upload-before` | `{ file: File, context: SchemaContext, currentNode?: CategoryNode }` | 上传前触发,包含文件对象和当前上下文(如选中节点) |
|
|
120
140
|
| `upload-success` | `response: any` | 上传成功后触发 |
|
|
121
141
|
| `upload-error` | `error: any` | 上传失败后触发 |
|
|
122
142
|
| `delete-before` | `file: FileItem` | 用户点击删除确认后,执行删除逻辑前触发 |
|
|
@@ -140,19 +160,38 @@ const mySchema = reactive<TreeUploadSchema>({
|
|
|
140
160
|
|
|
141
161
|
**节点配置 (CategoryNode)**:
|
|
142
162
|
- `required`: 是否必须上传文件。
|
|
163
|
+
- `mode`: 节点模式。可单独设置为 `view` 或 `edit`,优先级高于组件 `mode`。
|
|
143
164
|
- `minCount` / `maxCount`: 文件数量限制。
|
|
144
165
|
- `maxSize`: 单个文件大小限制 (Bytes)。
|
|
145
166
|
- `accept`: 允许的文件类型 (如 `.jpg,.png`)。
|
|
167
|
+
- `beforeUpload`: 节点级上传前校验钩子,返回 `false` 可阻止上传。
|
|
168
|
+
- `meta.upload.beforeUpload`: 节点 meta 内上传前校验钩子,返回 `false` 可阻止上传。
|
|
146
169
|
- `meta.templates`: 模板文件列表,选中节点时会自动显示在顶部。
|
|
147
170
|
|
|
171
|
+
模式优先级:
|
|
172
|
+
- `currentNode.mode`
|
|
173
|
+
- `currentNode.meta.mode`
|
|
174
|
+
- 组件 `mode`(`<TreeUpload mode="...">`)
|
|
175
|
+
|
|
176
|
+
当最终模式为 `view` 时,上传区隐藏且文件删除操作不可用;为 `edit` 时可上传并可删除。
|
|
177
|
+
|
|
148
178
|
#### 2. Upload Schema (`upload`)
|
|
149
179
|
|
|
150
180
|
| 字段 | 类型 | 说明 |
|
|
151
181
|
| --- | --- | --- |
|
|
152
182
|
| `action` | `string` | 上传接口地址 |
|
|
153
183
|
| `accept` | `string` | 全局文件类型限制 (会被节点配置覆盖) |
|
|
184
|
+
| `beforeUpload` | `(payload) => boolean \| void \| Promise<boolean \| void>` | 全局上传前校验钩子,返回 `false` 阻止上传 |
|
|
185
|
+
| `transformResponse` | `(res: any) => Partial<FileItem>` | 将接口响应转换为组件所需的 `FileItem` 格式 |
|
|
154
186
|
| `ui.showTip` | `boolean` | 是否显示动态提示文案 (自动聚合大小、数量、格式限制) |
|
|
155
187
|
|
|
188
|
+
上传前钩子执行顺序:
|
|
189
|
+
- `upload.beforeUpload`(全局)
|
|
190
|
+
- `currentNode.meta.upload.beforeUpload`(节点 meta)
|
|
191
|
+
- `currentNode.beforeUpload`(节点字段)
|
|
192
|
+
|
|
193
|
+
任意一个钩子返回 `false` 都会取消上传。
|
|
194
|
+
|
|
156
195
|
#### 3. Table Schema (`table`)
|
|
157
196
|
|
|
158
197
|
| 字段 | 类型 | 说明 |
|
|
@@ -161,6 +200,10 @@ const mySchema = reactive<TreeUploadSchema>({
|
|
|
161
200
|
| `columns` | `TableColumnSchema[]` | 列定义。支持 `formatter: 'fileSize'` |
|
|
162
201
|
| `ui.pagination` | `{ enabled: boolean, pageSize: number }` | 分页配置 (无数据时自动隐藏) |
|
|
163
202
|
|
|
203
|
+
行级按钮控制(FileItem):
|
|
204
|
+
- `actions`: 当前行允许的操作列表,支持字符串数组或对象数组。
|
|
205
|
+
- `disabledActions`: 当前行禁用的操作 key 列表。
|
|
206
|
+
|
|
164
207
|
## 🛠 开发与构建
|
|
165
208
|
|
|
166
209
|
```bash
|
|
@@ -2,6 +2,7 @@ import { TableSchema, FileItem } from '../types';
|
|
|
2
2
|
type __VLS_Props = {
|
|
3
3
|
schema: TableSchema;
|
|
4
4
|
files?: FileItem[];
|
|
5
|
+
mode?: 'view' | 'edit';
|
|
5
6
|
};
|
|
6
7
|
declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
7
8
|
action: (...args: any[]) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.schema-tree{height:100%;position:relative;display:flex;flex-direction:column}.tree-toolbar{padding:8px;border-bottom:1px solid var(--el-border-color-lighter);display:flex;gap:8px}.custom-tree-node{flex:1;display:flex;align-items:center;justify-content:space-between;font-size:14px;padding-right:8px}.custom-tree-node .actions{display:none}.custom-tree-node:hover .actions{display:inline-flex}.context-menu{position:fixed;z-index:1000;background:var(--el-bg-color-overlay);border:1px solid var(--el-border-color);box-shadow:var(--el-box-shadow-light);border-radius:4px;padding:5px 0;min-width:120px}.context-menu-item{padding:8px 16px;cursor:pointer;display:flex;align-items:center;gap:8px;font-size:13px;color:var(--el-text-color-regular)}.context-menu-item:hover{background-color:var(--el-fill-color-light);color:var(--el-color-primary)}.node-label{display:flex;align-items:center}.required-star{color:var(--el-color-danger);margin-right:4px;font-weight:700}.schema-upload[data-v-
|
|
1
|
+
.schema-tree{height:100%;position:relative;display:flex;flex-direction:column}.tree-toolbar{padding:8px;border-bottom:1px solid var(--el-border-color-lighter);display:flex;gap:8px}.custom-tree-node{flex:1;display:flex;align-items:center;justify-content:space-between;font-size:14px;padding-right:8px}.custom-tree-node .actions{display:none}.custom-tree-node:hover .actions{display:inline-flex}.context-menu{position:fixed;z-index:1000;background:var(--el-bg-color-overlay);border:1px solid var(--el-border-color);box-shadow:var(--el-box-shadow-light);border-radius:4px;padding:5px 0;min-width:120px}.context-menu-item{padding:8px 16px;cursor:pointer;display:flex;align-items:center;gap:8px;font-size:13px;color:var(--el-text-color-regular)}.context-menu-item:hover{background-color:var(--el-fill-color-light);color:var(--el-color-primary)}.node-label{display:flex;align-items:center}.required-star{color:var(--el-color-danger);margin-right:4px;font-weight:700}.schema-upload[data-v-47902547]{width:100%}.schema-table{height:100%;display:flex;flex-direction:column}.table-toolbar{margin-bottom:12px}.pagination-wrapper{margin-top:12px;display:flex;justify-content:flex-end}.schema-template{margin-bottom:12px;background-color:var(--el-fill-color-light);padding:8px 12px;border-radius:4px;border:1px solid var(--el-border-color-light)}.template-container{display:flex;align-items:center;flex-wrap:wrap;gap:8px}.label{font-size:13px;color:var(--el-text-color-secondary);white-space:nowrap}.tags-wrapper{display:flex;flex-wrap:wrap;gap:8px}.template-tag{cursor:pointer;border:none;background-color:var(--el-bg-color);transition:all .2s}.template-tag:hover{color:var(--el-color-primary);transform:translateY(-1px);box-shadow:var(--el-box-shadow-lighter)}.tag-content{display:flex;align-items:center;gap:4px}.tpl-name{line-height:1}.preview-content{height:100%;min-height:500px;display:flex;flex-direction:column}.custom-header{display:flex;justify-content:space-between;align-items:center;padding-right:0}.header-controls{display:flex;align-items:center;gap:8px}.tree-upload-container{display:flex;height:100%;min-height:500px;border:1px solid var(--el-border-color);background:var(--el-bg-color);box-sizing:border-box;position:relative}.tree-pane{border-right:1px solid var(--el-border-color);height:100%;overflow-y:auto;padding:10px;box-sizing:border-box;flex-shrink:0}.resize-handle{width:5px;height:100%;cursor:col-resize;background-color:transparent;margin-left:-3px;z-index:10;position:relative;transition:background-color .2s}.resize-handle:hover,.resize-handle:active{background-color:var(--el-color-primary);opacity:.5}.tree-upload-content-pane{flex:1;display:flex;flex-direction:column;padding:16px;overflow:hidden}.top-section{margin-bottom:16px}.table-section{flex:1;overflow:hidden}
|