jordium-gantt-vue3 1.4.2 → 1.4.4
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 +519 -428
- package/dist/assets/jordium-gantt-vue3.css +1 -1
- package/dist/jordium-gantt-vue3-styles.js +1 -1
- package/dist/jordium-gantt-vue3.cjs.js +84 -134
- package/dist/jordium-gantt-vue3.es.js +20503 -18136
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
4
|
<a href="https://www.npmjs.com/package/jordium-gantt-vue3">
|
|
5
|
-
<img src="https://img.shields.io/npm/v/jordium-gantt-vue3
|
|
5
|
+
<img src="https://img.shields.io/npm/v/jordium-gantt-vue3?style=flat-square" alt="npm version">
|
|
6
|
+
</a>
|
|
7
|
+
<a href="https://www.npmjs.com/package/jordium-gantt-vue3">
|
|
8
|
+
<img src="https://img.shields.io/npm/dt/jordium-gantt-vue3?style=flat-square" alt="npm total">
|
|
6
9
|
</a>
|
|
7
10
|
<a href="https://opensource.org/licenses/MIT">
|
|
8
11
|
<img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License">
|
|
@@ -21,6 +24,7 @@
|
|
|
21
24
|
<p align="center">
|
|
22
25
|
<a href="./README.md">中文</a> |
|
|
23
26
|
<a href="./README-EN.md">English</a>
|
|
27
|
+
<a href="./CHANGELOG.md">更新日志</a>
|
|
24
28
|
</p>
|
|
25
29
|
|
|
26
30
|
<p align="center">现代化的 Vue 3 甘特图组件库,为项目管理和任务调度提供完整解决方案</p>
|
|
@@ -105,10 +109,7 @@ import 'jordium-gantt-vue3/dist/assets/jordium-gantt-vue3.css'
|
|
|
105
109
|
```vue
|
|
106
110
|
<template>
|
|
107
111
|
<div style="height: 600px;">
|
|
108
|
-
<GanttChart
|
|
109
|
-
:tasks="tasks"
|
|
110
|
-
:milestones="milestones"
|
|
111
|
-
/>
|
|
112
|
+
<GanttChart :tasks="tasks" :milestones="milestones" />
|
|
112
113
|
</div>
|
|
113
114
|
</template>
|
|
114
115
|
|
|
@@ -123,7 +124,7 @@ const tasks = ref([
|
|
|
123
124
|
name: '项目启动',
|
|
124
125
|
startDate: '2025-01-01',
|
|
125
126
|
endDate: '2025-01-10',
|
|
126
|
-
progress: 100
|
|
127
|
+
progress: 100,
|
|
127
128
|
},
|
|
128
129
|
{
|
|
129
130
|
id: 2,
|
|
@@ -131,7 +132,7 @@ const tasks = ref([
|
|
|
131
132
|
startDate: '2025-01-11',
|
|
132
133
|
endDate: '2025-01-20',
|
|
133
134
|
progress: 80,
|
|
134
|
-
predecessor: [1]
|
|
135
|
+
predecessor: [1],
|
|
135
136
|
},
|
|
136
137
|
{
|
|
137
138
|
id: 3,
|
|
@@ -139,8 +140,8 @@ const tasks = ref([
|
|
|
139
140
|
startDate: '2025-01-21',
|
|
140
141
|
endDate: '2025-02-05',
|
|
141
142
|
progress: 50,
|
|
142
|
-
predecessor: [2]
|
|
143
|
-
}
|
|
143
|
+
predecessor: [2],
|
|
144
|
+
},
|
|
144
145
|
])
|
|
145
146
|
|
|
146
147
|
const milestones = ref([
|
|
@@ -148,8 +149,8 @@ const milestones = ref([
|
|
|
148
149
|
id: 101,
|
|
149
150
|
name: '项目立项',
|
|
150
151
|
date: '2025-01-01',
|
|
151
|
-
type: 'milestone'
|
|
152
|
-
}
|
|
152
|
+
type: 'milestone',
|
|
153
|
+
},
|
|
153
154
|
])
|
|
154
155
|
</script>
|
|
155
156
|
```
|
|
@@ -158,6 +159,7 @@ const milestones = ref([
|
|
|
158
159
|
<span><strong>推荐使用 <a href="https://dovee.cc/a.php?anaxjgyz1ozZq2B">DOVE</a> VPN,快速、稳定。</strong></span> <span style="color:red;">(注意:请合法使用 VPN 资源)</span>
|
|
159
160
|
|
|
160
161
|
## 🌞 NPM包使用示例
|
|
162
|
+
|
|
161
163
|
请参考项目下的npm-demo,这是一个独立的项目,可以使用IDE单独浏览和启动,运行前请安装element plus以及jordium-gantt-vue3插件包
|
|
162
164
|
|
|
163
165
|
```bash
|
|
@@ -166,9 +168,10 @@ npm install element-plus
|
|
|
166
168
|
npm install jordium-gantt-vue3
|
|
167
169
|
npm run dev
|
|
168
170
|
```
|
|
171
|
+
|
|
169
172
|
---
|
|
170
173
|
|
|
171
|
-
##
|
|
174
|
+
## 组件指南
|
|
172
175
|
|
|
173
176
|
### GanttChart 组件
|
|
174
177
|
|
|
@@ -176,68 +179,71 @@ npm run dev
|
|
|
176
179
|
|
|
177
180
|
#### 基础属性
|
|
178
181
|
|
|
179
|
-
| 属性名
|
|
180
|
-
|
|
181
|
-
| `tasks`
|
|
182
|
-
| `milestones`
|
|
183
|
-
| `showToolbar`
|
|
184
|
-
| `useDefaultDrawer`
|
|
185
|
-
| `useDefaultMilestoneDialog` | `boolean` | `true`
|
|
186
|
-
| `autoSortByStartDate`
|
|
187
|
-
| `allowDragAndResize`
|
|
182
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
183
|
+
| --------------------------- | --------- | ------- | -------------------------------------------------------------- |
|
|
184
|
+
| `tasks` | `Task[]` | `[]` | 任务数据数组 |
|
|
185
|
+
| `milestones` | `Task[]` | `[]` | 里程碑数据数组(注意:类型为 Task[],需设置 type='milestone') |
|
|
186
|
+
| `showToolbar` | `boolean` | `true` | 是否显示工具栏 |
|
|
187
|
+
| `useDefaultDrawer` | `boolean` | `true` | 是否使用内置任务编辑抽屉(TaskDrawer) |
|
|
188
|
+
| `useDefaultMilestoneDialog` | `boolean` | `true` | 是否使用内置里程碑编辑对话框(MilestoneDialog) |
|
|
189
|
+
| `autoSortByStartDate` | `boolean` | `false` | 是否根据开始时间自动排序任务 |
|
|
190
|
+
| `allowDragAndResize` | `boolean` | `true` | 是否允许拖拽和调整任务/里程碑大小 |
|
|
191
|
+
| `enableTaskRowMove` | `boolean` | `false` | 是否允许拖拽和摆放TaskRow |
|
|
188
192
|
|
|
189
193
|
#### 配置对象属性
|
|
190
194
|
|
|
191
195
|
完整的配置对象说明请参考 [⚙️ 配置与扩展](#⚙️-配置与扩展) 章节。
|
|
192
196
|
|
|
193
|
-
| 属性名
|
|
194
|
-
|
|
195
|
-
| `toolbarConfig`
|
|
196
|
-
| `taskListConfig` | `TaskListConfig`
|
|
197
|
-
| `taskBarConfig`
|
|
198
|
-
| `localeMessages` | `Partial<Messages['zh-CN']>` | `undefined`
|
|
199
|
-
| `workingHours`
|
|
197
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
198
|
+
| ---------------- | ---------------------------- | ----------------------------------------------------------------------- | ---------------- |
|
|
199
|
+
| `toolbarConfig` | `ToolbarConfig` | `{}` | 工具栏配置 |
|
|
200
|
+
| `taskListConfig` | `TaskListConfig` | `undefined` | 任务列表配置 |
|
|
201
|
+
| `taskBarConfig` | `TaskBarConfig` | `undefined` | 任务条样式配置 |
|
|
202
|
+
| `localeMessages` | `Partial<Messages['zh-CN']>` | `undefined` | 自定义多语言配置 |
|
|
203
|
+
| `workingHours` | `WorkingHours` | `{ morning: { start: 8, end: 11 }, afternoon: { start: 13, end: 17 } }` | 工作时间配置 |
|
|
200
204
|
|
|
201
205
|
#### 回调函数属性
|
|
202
206
|
|
|
203
|
-
| 属性名
|
|
204
|
-
|
|
205
|
-
| `onTodayLocate`
|
|
206
|
-
| `onExportCsv`
|
|
207
|
-
| `onExportPdf`
|
|
208
|
-
| `onLanguageChange`
|
|
209
|
-
| `onThemeChange`
|
|
210
|
-
| `onFullscreenChange` | `(isFullscreen: boolean) => void`
|
|
211
|
-
| `onExpandAll`
|
|
212
|
-
| `onCollapseAll`
|
|
207
|
+
| 属性名 | 类型 | 说明 |
|
|
208
|
+
| -------------------- | ------------------------------------ | -------------------------------------------------------- |
|
|
209
|
+
| `onTodayLocate` | `() => void` | 工具栏"今天"按钮点击回调 |
|
|
210
|
+
| `onExportCsv` | `() => boolean \| void` | 工具栏"导出CSV"按钮点击回调,返回 `false` 可阻止默认导出 |
|
|
211
|
+
| `onExportPdf` | `() => void` | 工具栏"导出PDF"按钮点击回调 |
|
|
212
|
+
| `onLanguageChange` | `(lang: 'zh-CN' \| 'en-US') => void` | 语言切换回调 |
|
|
213
|
+
| `onThemeChange` | `(isDark: boolean) => void` | 主题切换回调 |
|
|
214
|
+
| `onFullscreenChange` | `(isFullscreen: boolean) => void` | 全屏切换回调 |
|
|
215
|
+
| `onExpandAll` | `() => void` | 工具栏"全部展开"按钮点击回调 |
|
|
216
|
+
| `onCollapseAll` | `() => void` | 工具栏"全部折叠"按钮点击回调 |
|
|
213
217
|
|
|
214
218
|
#### 组件事件(Events)
|
|
215
219
|
|
|
216
220
|
完整的事件说明请分别参考:
|
|
221
|
+
|
|
217
222
|
- **任务相关事件**:参见下方 [任务管理](#任务管理) 章节
|
|
218
223
|
- **里程碑相关事件**:参见下方 [里程碑管理](#里程碑管理) 章节
|
|
219
224
|
|
|
220
225
|
**事件列表总览:**
|
|
221
226
|
|
|
222
|
-
| 事件名
|
|
223
|
-
|
|
224
|
-
| `add-task`
|
|
225
|
-
| `task-click`
|
|
226
|
-
| `task-double-click`
|
|
227
|
-
| `task-added`
|
|
228
|
-
| `task-updated`
|
|
229
|
-
| `task-deleted`
|
|
230
|
-
| `taskbar-drag-end`
|
|
231
|
-
| `taskbar-resize-end`
|
|
232
|
-
| `predecessor-added`
|
|
233
|
-
| `successor-added`
|
|
234
|
-
| `timer-started`
|
|
235
|
-
| `timer-stopped`
|
|
236
|
-
| `add-milestone`
|
|
237
|
-
| `milestone-saved`
|
|
238
|
-
| `milestone-deleted`
|
|
239
|
-
| `milestone-icon-changed` | `{ milestoneId, icon }`
|
|
240
|
-
| `milestone-drag-end`
|
|
227
|
+
| 事件名 | 参数 | 说明 |
|
|
228
|
+
| ------------------------ | --------------------------------- | -------------------------- |
|
|
229
|
+
| `add-task` | - | 点击工具栏"添加任务"按钮 |
|
|
230
|
+
| `task-click` | `(task: Task, event: MouseEvent)` | 点击任务 |
|
|
231
|
+
| `task-double-click` | `(task: Task)` | 双击任务 |
|
|
232
|
+
| `task-added` | `{ task: Task }` | 任务添加后触发 |
|
|
233
|
+
| `task-updated` | `{ task: Task }` | 任务更新后触发 |
|
|
234
|
+
| `task-deleted` | `{ task: Task }` | 任务删除后触发 |
|
|
235
|
+
| `taskbar-drag-end` | `(task: Task)` | 拖拽任务结束 |
|
|
236
|
+
| `taskbar-resize-end` | `(task: Task)` | 调整任务大小结束 |
|
|
237
|
+
| `predecessor-added` | `{ targetTask, newTask }` | 添加前置任务 |
|
|
238
|
+
| `successor-added` | `{ targetTask, newTask }` | 添加后置任务 |
|
|
239
|
+
| `timer-started` | `(task: Task)` | 任务计时器启动 |
|
|
240
|
+
| `timer-stopped` | `(task: Task)` | 任务计时器停止 |
|
|
241
|
+
| `add-milestone` | - | 点击工具栏"添加里程碑"按钮 |
|
|
242
|
+
| `milestone-saved` | `(milestone: Task)` | 里程碑保存 |
|
|
243
|
+
| `milestone-deleted` | `{ milestoneId: number }` | 里程碑删除 |
|
|
244
|
+
| `milestone-icon-changed` | `{ milestoneId, icon }` | 里程碑图标变更 |
|
|
245
|
+
| `milestone-drag-end` | `(milestone: Task)` | 拖拽里程碑结束 |
|
|
246
|
+
| `task-row-moved` | `payload: { draggedTask: Task, targetTask: Task, position: 'after' 或 'child'}` | 拖拽TaskRow结束 |
|
|
241
247
|
|
|
242
248
|
#### 示例1:最简单的甘特图
|
|
243
249
|
|
|
@@ -259,8 +265,8 @@ const tasks = ref([
|
|
|
259
265
|
name: '任务1',
|
|
260
266
|
startDate: '2025-01-01',
|
|
261
267
|
endDate: '2025-01-10',
|
|
262
|
-
progress: 100
|
|
263
|
-
}
|
|
268
|
+
progress: 100,
|
|
269
|
+
},
|
|
264
270
|
])
|
|
265
271
|
</script>
|
|
266
272
|
```
|
|
@@ -270,10 +276,7 @@ const tasks = ref([
|
|
|
270
276
|
```vue
|
|
271
277
|
<template>
|
|
272
278
|
<div style="height: 600px;">
|
|
273
|
-
<GanttChart
|
|
274
|
-
:tasks="tasks"
|
|
275
|
-
:milestones="milestones"
|
|
276
|
-
/>
|
|
279
|
+
<GanttChart :tasks="tasks" :milestones="milestones" />
|
|
277
280
|
</div>
|
|
278
281
|
</template>
|
|
279
282
|
|
|
@@ -288,8 +291,8 @@ const tasks = ref([
|
|
|
288
291
|
name: '项目启动',
|
|
289
292
|
startDate: '2025-01-01',
|
|
290
293
|
endDate: '2025-01-10',
|
|
291
|
-
progress: 100
|
|
292
|
-
}
|
|
294
|
+
progress: 100,
|
|
295
|
+
},
|
|
293
296
|
])
|
|
294
297
|
|
|
295
298
|
const milestones = ref([
|
|
@@ -298,8 +301,8 @@ const milestones = ref([
|
|
|
298
301
|
name: '项目立项',
|
|
299
302
|
startDate: '2025-01-01',
|
|
300
303
|
type: 'milestone',
|
|
301
|
-
icon: 'diamond'
|
|
302
|
-
}
|
|
304
|
+
icon: 'diamond',
|
|
305
|
+
},
|
|
303
306
|
])
|
|
304
307
|
</script>
|
|
305
308
|
```
|
|
@@ -314,10 +317,10 @@ const milestones = ref([
|
|
|
314
317
|
<button @click="addTask">新增任务</button>
|
|
315
318
|
<button @click="addMilestone">新增里程碑</button>
|
|
316
319
|
</div>
|
|
317
|
-
|
|
320
|
+
|
|
318
321
|
<!-- 甘特图组件,隐藏内置工具栏 -->
|
|
319
322
|
<div style="height: 600px;">
|
|
320
|
-
<GanttChart
|
|
323
|
+
<GanttChart
|
|
321
324
|
:tasks="tasks"
|
|
322
325
|
:milestones="milestones"
|
|
323
326
|
:show-toolbar="false"
|
|
@@ -342,7 +345,7 @@ const addTask = () => {
|
|
|
342
345
|
name: '新任务',
|
|
343
346
|
startDate: new Date().toISOString().split('T')[0],
|
|
344
347
|
endDate: new Date().toISOString().split('T')[0],
|
|
345
|
-
progress: 0
|
|
348
|
+
progress: 0,
|
|
346
349
|
}
|
|
347
350
|
tasks.value.push(newTask)
|
|
348
351
|
}
|
|
@@ -352,16 +355,16 @@ const addMilestone = () => {
|
|
|
352
355
|
id: Date.now(),
|
|
353
356
|
name: '新里程碑',
|
|
354
357
|
startDate: new Date().toISOString().split('T')[0],
|
|
355
|
-
type: 'milestone'
|
|
358
|
+
type: 'milestone',
|
|
356
359
|
}
|
|
357
360
|
milestones.value.push(newMilestone)
|
|
358
361
|
}
|
|
359
362
|
|
|
360
|
-
const handleTaskAdded =
|
|
363
|
+
const handleTaskAdded = e => {
|
|
361
364
|
console.log('任务已添加:', e.task)
|
|
362
365
|
}
|
|
363
366
|
|
|
364
|
-
const handleMilestoneSaved =
|
|
367
|
+
const handleMilestoneSaved = milestone => {
|
|
365
368
|
console.log('里程碑已保存:', milestone)
|
|
366
369
|
}
|
|
367
370
|
</script>
|
|
@@ -375,37 +378,38 @@ const handleMilestoneSaved = (milestone) => {
|
|
|
375
378
|
|
|
376
379
|
#### Task 数据结构
|
|
377
380
|
|
|
378
|
-
| 字段名
|
|
379
|
-
|
|
380
|
-
| `id`
|
|
381
|
-
| `name`
|
|
382
|
-
| `startDate`
|
|
383
|
-
| `endDate`
|
|
384
|
-
| `progress`
|
|
385
|
-
| `predecessor`
|
|
386
|
-
| `assignee`
|
|
387
|
-
| `avatar`
|
|
388
|
-
| `estimatedHours`
|
|
389
|
-
| `actualHours`
|
|
390
|
-
| `parentId`
|
|
391
|
-
| `children`
|
|
392
|
-
| `collapsed`
|
|
393
|
-
| `isParent`
|
|
394
|
-
| `type`
|
|
395
|
-
| `description`
|
|
396
|
-
| `icon`
|
|
397
|
-
| `level`
|
|
398
|
-
| `isTimerRunning`
|
|
399
|
-
| `timerStartTime`
|
|
400
|
-
| `timerEndTime`
|
|
401
|
-
| `timerStartDesc`
|
|
402
|
-
| `timerElapsedTime` | `number`
|
|
403
|
-
| `isEditable`
|
|
404
|
-
| `[key: string]`
|
|
381
|
+
| 字段名 | 类型 | 必填 | 默认值 | 说明 |
|
|
382
|
+
| ------------------ | ---------- | ---- | ----------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
|
383
|
+
| `id` | `number` | ✅ | - | 任务唯一标识符 |
|
|
384
|
+
| `name` | `string` | ✅ | - | 任务名称 |
|
|
385
|
+
| `startDate` | `string` | - | - | 开始日期,格式:'YYYY-MM-DD' 或 'YYYY-MM-DD HH:mm' |
|
|
386
|
+
| `endDate` | `string` | - | - | 结束日期,格式:'YYYY-MM-DD' 或 'YYYY-MM-DD HH:mm' |
|
|
387
|
+
| `progress` | `number` | - | `0` | 任务进度,范围 0-100 |
|
|
388
|
+
| `predecessor` | `number[]` | - | - | 前置任务 ID 数组,标准格式:`[1, 2, 3]`<br/>**兼容格式**:也支持字符串 `'1,2,3'` 或字符串数组 `['1', '2', '3']`,组件会自动解析 |
|
|
389
|
+
| `assignee` | `string` | - | - | 任务负责人 |
|
|
390
|
+
| `avatar` | `string` | - | - | 任务负责人头像 URL |
|
|
391
|
+
| `estimatedHours` | `number` | - | - | 预估工时(小时) |
|
|
392
|
+
| `actualHours` | `number` | - | - | 实际工时(小时) |
|
|
393
|
+
| `parentId` | `number` | - | - | 父任务 ID,用于任务分组 |
|
|
394
|
+
| `children` | `Task[]` | - | - | 子任务数组 |
|
|
395
|
+
| `collapsed` | `boolean` | - | `false` | 子任务是否折叠 |
|
|
396
|
+
| `isParent` | `boolean` | - | - | 是否为父任务 |
|
|
397
|
+
| `type` | `string` | - | - | 任务类型,'milestone' 表示里程碑,'milestone-group' 表示里程碑分组 |
|
|
398
|
+
| `description` | `string` | - | - | 任务描述 |
|
|
399
|
+
| `icon` | `string` | - | `'diamond'` | 任务图标(用于里程碑),可选值:'diamond', 'flag', 'star', 'rocket' 等 |
|
|
400
|
+
| `level` | `number` | - | `0` | 任务层级(自动计算) |
|
|
401
|
+
| `isTimerRunning` | `boolean` | - | `false` | 计时器是否运行中 |
|
|
402
|
+
| `timerStartTime` | `number` | - | - | 计时开始时间(时间戳) |
|
|
403
|
+
| `timerEndTime` | `number` | - | - | 计时结束时间(时间戳) |
|
|
404
|
+
| `timerStartDesc` | `string` | - | - | 计时开始时填写的描述 |
|
|
405
|
+
| `timerElapsedTime` | `number` | - | `0` | 已计时的时长(毫秒) |
|
|
406
|
+
| `isEditable` | `boolean` | - | `true` | 单个任务是否可编辑(可拖拽、拉伸),优先级高于全局 `allowDragAndResize` |
|
|
407
|
+
| `[key: string]` | `unknown` | - | - | 支持自定义属性扩展,可添加任意额外字段 |
|
|
405
408
|
|
|
406
409
|
> **自定义属性扩展**:Task 接口支持添加任意自定义字段,例如:`priority`、`tags`、`status`、`department` 等业务相关字段。
|
|
407
|
-
>
|
|
410
|
+
>
|
|
408
411
|
> **前置任务字段说明**:
|
|
412
|
+
>
|
|
409
413
|
> - **标准格式**(推荐):`predecessor: [1, 2, 3]` - number 数组
|
|
410
414
|
> - **兼容格式1**:`predecessor: '1,2,3'` - 逗号分隔的字符串
|
|
411
415
|
> - **兼容格式2**:`predecessor: ['1', '2', '3']` - 字符串数组
|
|
@@ -414,15 +418,17 @@ const handleMilestoneSaved = (milestone) => {
|
|
|
414
418
|
|
|
415
419
|
#### 任务相关属性
|
|
416
420
|
|
|
417
|
-
| 属性名
|
|
418
|
-
|
|
419
|
-
| `tasks`
|
|
420
|
-
| `useDefaultDrawer`
|
|
421
|
-
| `taskBarConfig`
|
|
422
|
-
| `taskListConfig`
|
|
423
|
-
| `autoSortByStartDate` | `boolean`
|
|
421
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
422
|
+
| --------------------- | ---------------- | ----------- | -------------------------------------------------------------- |
|
|
423
|
+
| `tasks` | `Task[]` | `[]` | 任务数据数组 |
|
|
424
|
+
| `useDefaultDrawer` | `boolean` | `true` | 是否使用内置的任务编辑抽屉(TaskDrawer) |
|
|
425
|
+
| `taskBarConfig` | `TaskBarConfig` | `{}` | 任务条样式配置,详见 [TaskBarConfig 配置](#taskbarconfig-配置) |
|
|
426
|
+
| `taskListConfig` | `TaskListConfig` | `undefined` | 任务列表配置,详见 [TaskListConfig 配置](#tasklistconfig-配置) |
|
|
427
|
+
| `autoSortByStartDate` | `boolean` | `false` | 是否根据开始时间自动排序任务 |
|
|
428
|
+
| `enableTaskRowMove` | `boolean` | `false` | 是否允许拖拽和摆放TaskRow
|
|
424
429
|
|
|
425
430
|
**配置说明**:
|
|
431
|
+
|
|
426
432
|
- **默认模式**:`useDefaultDrawer=true`(默认),双击任务自动打开内置 TaskDrawer
|
|
427
433
|
- **自定义编辑器**:`useDefaultDrawer=false` 禁用内置抽屉,监听 `@task-double-click` 事件打开自定义编辑器
|
|
428
434
|
- **只读模式**:`useDefaultDrawer=false` 且不监听 `@task-double-click` 事件,用户双击任务无反应
|
|
@@ -431,22 +437,24 @@ const handleMilestoneSaved = (milestone) => {
|
|
|
431
437
|
|
|
432
438
|
> **💡 事件驱动架构**:组件采用纯事件驱动设计,所有用户操作(添加、编辑、删除、拖拽等)都会触发对应事件,方便外部监听和处理。
|
|
433
439
|
|
|
434
|
-
| 事件名
|
|
435
|
-
|
|
436
|
-
| `add-task`
|
|
437
|
-
| `task-click`
|
|
438
|
-
| `task-double-click`
|
|
439
|
-
| `task-added`
|
|
440
|
-
| `task-updated`
|
|
441
|
-
| `task-deleted`
|
|
442
|
-
| `taskbar-drag-end`
|
|
443
|
-
| `taskbar-resize-end` | `(task: Task) => void`
|
|
444
|
-
| `predecessor-added`
|
|
445
|
-
| `successor-added`
|
|
446
|
-
| `timer-started`
|
|
447
|
-
| `timer-stopped`
|
|
440
|
+
| 事件名 | 参数 | 触发时机 | 说明 |
|
|
441
|
+
| -------------------- | ----------------------------------------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
|
|
442
|
+
| `add-task` | - | 点击工具栏"添加任务"按钮时 | 可用于自定义新增任务逻辑。如 `useDefaultDrawer=true`,组件会自动打开内置 TaskDrawer |
|
|
443
|
+
| `task-click` | `(task: Task, event: MouseEvent) => void` | 点击任务条时 | 单击任务触发 |
|
|
444
|
+
| `task-double-click` | `(task: Task) => void` | 双击任务条时 | 双击任务时**始终触发**。`useDefaultDrawer=true` 时组件会额外打开内置编辑器,`false` 时不打开。事件触发与属性值无关 |
|
|
445
|
+
| `task-added` | `{ task: Task }` | 任务添加后 | 通过内置 TaskDrawer 添加任务后触发。**注意**:组件已自动更新 `tasks` 数据,外部只需监听此事件做额外处理(如调用 API 保存) |
|
|
446
|
+
| `task-updated` | `{ task: Task }` | 任务更新后 | 通过内置 TaskDrawer 或拖拽更新任务后触发。**注意**:组件已自动更新 `tasks` 数据,外部只需监听此事件做额外处理 |
|
|
447
|
+
| `task-deleted` | `{ task: Task }` | 任务删除后 | 通过内置 TaskDrawer 删除任务后触发。**注意**:组件已自动更新 `tasks` 数据,外部只需监听此事件做额外处理 |
|
|
448
|
+
| `taskbar-drag-end` | `(task: Task) => void` | 拖拽任务条结束时 | 任务位置变化,startDate 和 endDate 已更新。**注意**:组件已自动更新 `tasks` 数据 |
|
|
449
|
+
| `taskbar-resize-end` | `(task: Task) => void` | 调整任务条大小结束时 | 任务时长变化,endDate 已更新。**注意**:组件已自动更新 `tasks` 数据 |
|
|
450
|
+
| `predecessor-added` | `{ targetTask: Task, newTask: Task }` | 通过右键菜单添加前置任务后 | `targetTask` 是被添加前置任务的任务,`newTask` 是新创建的前置任务 |
|
|
451
|
+
| `successor-added` | `{ targetTask: Task, newTask: Task }` | 通过右键菜单添加后置任务后 | `targetTask` 是原任务,`newTask` 是新创建的后置任务(其 predecessor 已包含 targetTask.id) |
|
|
452
|
+
| `timer-started` | `(task: Task) => void` | 任务计时器启动时 | 开始记录任务工时 |
|
|
453
|
+
| `timer-stopped` | `(task: Task) => void` | 任务计时器停止时 | 停止记录任务工时 |
|
|
454
|
+
| `task-row-moved` | `payload: { draggedTask: Task, targetTask: Task, position: 'after' 或 'child'}` | 拖拽TaskRow结束 | TaskList中的TasRow按住拖拽,完成前后排放位置放置后
|
|
448
455
|
|
|
449
456
|
**数据同步说明**:
|
|
457
|
+
|
|
450
458
|
- ✅ **组件内部自动更新**:所有任务的增删改操作,组件都会自动更新 `props.tasks` 数据
|
|
451
459
|
- ✅ **事件仅做通知**:外部监听事件主要用于:显示提示消息、调用后端 API、更新其他相关数据等
|
|
452
460
|
- ❌ **避免重复操作**:不要在事件处理器中再次修改 `tasks` 数据,否则会导致重复更新
|
|
@@ -456,7 +464,7 @@ const handleMilestoneSaved = (milestone) => {
|
|
|
456
464
|
```vue
|
|
457
465
|
<template>
|
|
458
466
|
<div style="height: 600px;">
|
|
459
|
-
<GanttChart
|
|
467
|
+
<GanttChart
|
|
460
468
|
:tasks="tasks"
|
|
461
469
|
@add-task="handleAddTask"
|
|
462
470
|
@task-added="handleTaskAdded"
|
|
@@ -492,7 +500,7 @@ const tasks = ref<Task[]>([
|
|
|
492
500
|
progress: 60,
|
|
493
501
|
assignee: '李四',
|
|
494
502
|
predecessor: [1], // 依赖任务1
|
|
495
|
-
}
|
|
503
|
+
},
|
|
496
504
|
])
|
|
497
505
|
|
|
498
506
|
// 工具栏"添加任务"按钮点击事件
|
|
@@ -545,7 +553,7 @@ const handleTaskDragEnd = (task: Task) => {
|
|
|
545
553
|
|
|
546
554
|
```vue
|
|
547
555
|
<template>
|
|
548
|
-
<GanttChart
|
|
556
|
+
<GanttChart
|
|
549
557
|
:tasks="tasks"
|
|
550
558
|
@predecessor-added="handlePredecessorAdded"
|
|
551
559
|
@successor-added="handleSuccessorAdded"
|
|
@@ -565,7 +573,7 @@ const tasks = ref<Task[]>([
|
|
|
565
573
|
startDate: '2025-01-01',
|
|
566
574
|
endDate: '2025-01-10',
|
|
567
575
|
progress: 100,
|
|
568
|
-
predecessor: [] // 无前置任务
|
|
576
|
+
predecessor: [], // 无前置任务
|
|
569
577
|
},
|
|
570
578
|
{
|
|
571
579
|
id: 2,
|
|
@@ -573,7 +581,7 @@ const tasks = ref<Task[]>([
|
|
|
573
581
|
startDate: '2025-01-11',
|
|
574
582
|
endDate: '2025-01-20',
|
|
575
583
|
progress: 80,
|
|
576
|
-
predecessor: [1] // 依赖任务1(需求分析)
|
|
584
|
+
predecessor: [1], // 依赖任务1(需求分析)
|
|
577
585
|
},
|
|
578
586
|
{
|
|
579
587
|
id: 3,
|
|
@@ -581,7 +589,7 @@ const tasks = ref<Task[]>([
|
|
|
581
589
|
startDate: '2025-01-11',
|
|
582
590
|
endDate: '2025-01-18',
|
|
583
591
|
progress: 90,
|
|
584
|
-
predecessor: [1] // 依赖任务1
|
|
592
|
+
predecessor: [1], // 依赖任务1
|
|
585
593
|
},
|
|
586
594
|
{
|
|
587
595
|
id: 4,
|
|
@@ -589,7 +597,7 @@ const tasks = ref<Task[]>([
|
|
|
589
597
|
startDate: '2025-01-21',
|
|
590
598
|
endDate: '2025-02-10',
|
|
591
599
|
progress: 60,
|
|
592
|
-
predecessor: [2] // 依赖任务2(系统设计)
|
|
600
|
+
predecessor: [2], // 依赖任务2(系统设计)
|
|
593
601
|
},
|
|
594
602
|
{
|
|
595
603
|
id: 5,
|
|
@@ -597,7 +605,7 @@ const tasks = ref<Task[]>([
|
|
|
597
605
|
startDate: '2025-01-19',
|
|
598
606
|
endDate: '2025-02-08',
|
|
599
607
|
progress: 70,
|
|
600
|
-
predecessor: [2, 3] // 同时依赖任务2和3
|
|
608
|
+
predecessor: [2, 3], // 同时依赖任务2和3
|
|
601
609
|
},
|
|
602
610
|
{
|
|
603
611
|
id: 6,
|
|
@@ -605,8 +613,8 @@ const tasks = ref<Task[]>([
|
|
|
605
613
|
startDate: '2025-02-11',
|
|
606
614
|
endDate: '2025-02-20',
|
|
607
615
|
progress: 30,
|
|
608
|
-
predecessor: [4, 5] // 依赖前端和后端开发完成
|
|
609
|
-
}
|
|
616
|
+
predecessor: [4, 5], // 依赖前端和后端开发完成
|
|
617
|
+
},
|
|
610
618
|
])
|
|
611
619
|
|
|
612
620
|
// 通过右键菜单添加前置任务时触发
|
|
@@ -628,6 +636,7 @@ const handleSuccessorAdded = (event: { targetTask: Task; newTask: Task }) => {
|
|
|
628
636
|
```
|
|
629
637
|
|
|
630
638
|
**依赖关系说明**:
|
|
639
|
+
|
|
631
640
|
- **`predecessor` 字段支持多种格式**:
|
|
632
641
|
- 标准格式(推荐):`[1, 2, 3]` - number 数组
|
|
633
642
|
- 兼容格式1:`'1,2,3'` - 逗号分隔的字符串
|
|
@@ -653,9 +662,9 @@ const handleSuccessorAdded = (event: { targetTask: Task; newTask: Task }) => {
|
|
|
653
662
|
<button @click="triggerAddMilestone">新增里程碑</button>
|
|
654
663
|
<!-- 其他自定义按钮... -->
|
|
655
664
|
</div>
|
|
656
|
-
|
|
665
|
+
|
|
657
666
|
<!-- 甘特图组件,隐藏内置工具栏 -->
|
|
658
|
-
<GanttChart
|
|
667
|
+
<GanttChart
|
|
659
668
|
:tasks="tasks"
|
|
660
669
|
:milestones="milestones"
|
|
661
670
|
:show-toolbar="false"
|
|
@@ -696,7 +705,7 @@ const handleAddMilestone = () => {
|
|
|
696
705
|
console.log('准备新增里程碑(由自定义按钮触发)')
|
|
697
706
|
}
|
|
698
707
|
|
|
699
|
-
const handleTaskAdded =
|
|
708
|
+
const handleTaskAdded = e => {
|
|
700
709
|
console.log('任务已添加:', e.task)
|
|
701
710
|
// 调用 API 保存...
|
|
702
711
|
}
|
|
@@ -704,10 +713,103 @@ const handleTaskAdded = (e) => {
|
|
|
704
713
|
```
|
|
705
714
|
|
|
706
715
|
> **💡 灵活性设计**:
|
|
716
|
+
>
|
|
707
717
|
> - 显示工具栏 + 默认编辑器:最简单的开箱即用方式
|
|
708
718
|
> - 隐藏工具栏 + 自定义按钮 + 默认编辑器:自定义控制栏样式,保留默认编辑功能
|
|
709
719
|
> - 隐藏工具栏 + 自定义按钮 + 自定义编辑器:完全自定义所有交互逻辑
|
|
710
720
|
|
|
721
|
+
#### 示例4:任务行拖拽排序
|
|
722
|
+
|
|
723
|
+
允许用户通过拖拽 TaskRow 来调整任务的层级关系和前后顺序:
|
|
724
|
+
|
|
725
|
+
```vue
|
|
726
|
+
<template>
|
|
727
|
+
<div style="height: 600px;">
|
|
728
|
+
<GanttChart
|
|
729
|
+
:tasks="tasks"
|
|
730
|
+
:enable-task-row-move="true"
|
|
731
|
+
@task-row-moved="handleTaskRowMoved"
|
|
732
|
+
/>
|
|
733
|
+
</div>
|
|
734
|
+
</template>
|
|
735
|
+
|
|
736
|
+
<script setup lang="ts">
|
|
737
|
+
import { ref } from 'vue'
|
|
738
|
+
import { GanttChart } from 'jordium-gantt-vue3'
|
|
739
|
+
import type { Task } from 'jordium-gantt-vue3'
|
|
740
|
+
import 'jordium-gantt-vue3/dist/assets/jordium-gantt-vue3.css'
|
|
741
|
+
|
|
742
|
+
const tasks = ref<Task[]>([
|
|
743
|
+
{
|
|
744
|
+
id: 1,
|
|
745
|
+
name: '项目规划',
|
|
746
|
+
startDate: '2025-01-01',
|
|
747
|
+
endDate: '2025-01-10',
|
|
748
|
+
progress: 100,
|
|
749
|
+
},
|
|
750
|
+
{
|
|
751
|
+
id: 2,
|
|
752
|
+
name: '需求分析',
|
|
753
|
+
startDate: '2025-01-11',
|
|
754
|
+
endDate: '2025-01-20',
|
|
755
|
+
progress: 60,
|
|
756
|
+
parentId: 1,
|
|
757
|
+
},
|
|
758
|
+
{
|
|
759
|
+
id: 3,
|
|
760
|
+
name: '系统设计',
|
|
761
|
+
startDate: '2025-01-21',
|
|
762
|
+
endDate: '2025-01-30',
|
|
763
|
+
progress: 40,
|
|
764
|
+
},
|
|
765
|
+
])
|
|
766
|
+
|
|
767
|
+
// 任务行拖拽完成事件
|
|
768
|
+
const handleTaskRowMoved = (payload: {
|
|
769
|
+
draggedTask: Task
|
|
770
|
+
targetTask: Task
|
|
771
|
+
position: 'after' | 'child'
|
|
772
|
+
}) => {
|
|
773
|
+
const { draggedTask, targetTask, position } = payload
|
|
774
|
+
|
|
775
|
+
console.log(`任务 [${draggedTask.name}] 被拖拽到任务 [${targetTask.name}] ${position === 'after' ? '之后' : '下方作为子任务'}`)
|
|
776
|
+
|
|
777
|
+
// 组件已自动更新任务的层级关系和位置
|
|
778
|
+
// position === 'after': 任务被放置在目标任务之后(同级)
|
|
779
|
+
// position === 'child': 任务被放置为目标任务的子任务(第一个子任务位置)
|
|
780
|
+
|
|
781
|
+
// 这里可以:
|
|
782
|
+
// 1. 显示确认对话框,让用户确认是否移动
|
|
783
|
+
// 2. 调用后端 API 保存新的任务层级关系
|
|
784
|
+
// 3. 更新相关的依赖关系
|
|
785
|
+
|
|
786
|
+
// 示例:调用后端 API
|
|
787
|
+
// await api.updateTaskHierarchy({
|
|
788
|
+
// taskId: draggedTask.id,
|
|
789
|
+
// targetTaskId: targetTask.id,
|
|
790
|
+
// position: position
|
|
791
|
+
// })
|
|
792
|
+
}
|
|
793
|
+
</script>
|
|
794
|
+
```
|
|
795
|
+
|
|
796
|
+
**拖拽排序说明**:
|
|
797
|
+
|
|
798
|
+
- **启用拖拽**:设置 `enable-task-row-move="true"` 启用任务行拖拽功能(默认为 `false`)
|
|
799
|
+
- **拖拽算法**:
|
|
800
|
+
- **算法1(放置在后面)**:当目标任务没有子任务时,被拖拽的任务会放置在目标任务之后(同级),`position='after'`
|
|
801
|
+
- **算法2(作为子任务)**:当目标任务有子任务时,被拖拽的任务会成为目标任务的第一个子任务,`position='child'`
|
|
802
|
+
- **视觉反馈**:
|
|
803
|
+
- 拖拽时会显示半透明的跟随元素
|
|
804
|
+
- 悬停在有效目标任务上时显示蓝色边框提示
|
|
805
|
+
- 无子任务的任务显示蓝色底部边框
|
|
806
|
+
- 有子任务的任务显示蓝色四周边框
|
|
807
|
+
- **自动更新**:组件会自动更新任务的 `parentId` 字段和 `children` 数组,外部只需监听事件做额外处理(如保存到后端)
|
|
808
|
+
- **限制条件**:
|
|
809
|
+
- 不能拖拽到自己身上
|
|
810
|
+
- 不能拖拽到自己的子任务上(避免循环引用)
|
|
811
|
+
- 里程碑和里程碑分组不能被拖拽
|
|
812
|
+
|
|
711
813
|
### 里程碑管理
|
|
712
814
|
|
|
713
815
|
里程碑用于标记项目中的重要时间节点,如项目启动、阶段完成、产品发布等。组件提供了灵活的里程碑编辑配置,默认使用内置的 MilestoneDialog,也支持完全自定义编辑行为。
|
|
@@ -716,32 +818,34 @@ const handleTaskAdded = (e) => {
|
|
|
716
818
|
|
|
717
819
|
#### Milestone 数据结构
|
|
718
820
|
|
|
719
|
-
| 字段名
|
|
720
|
-
|
|
721
|
-
| `id`
|
|
722
|
-
| `name`
|
|
723
|
-
| `startDate`
|
|
724
|
-
| `endDate`
|
|
725
|
-
| `assignee`
|
|
726
|
-
| `type`
|
|
727
|
-
| `icon`
|
|
728
|
-
| `description` | `string` | -
|
|
821
|
+
| 字段名 | 类型 | 必填 | 默认值 | 说明 |
|
|
822
|
+
| ------------- | -------- | ---- | ------------- | ---------------------------------------------------------- |
|
|
823
|
+
| `id` | `number` | ✅ | - | 里程碑唯一标识符 |
|
|
824
|
+
| `name` | `string` | ✅ | - | 里程碑名称 |
|
|
825
|
+
| `startDate` | `string` | ✅ | - | 里程碑日期,格式:'YYYY-MM-DD' 或 'YYYY-MM-DD HH:mm' |
|
|
826
|
+
| `endDate` | `string` | - | - | 结束日期(通常里程碑不需要,自动设置为与 startDate 相同) |
|
|
827
|
+
| `assignee` | `string` | - | - | 负责人 |
|
|
828
|
+
| `type` | `string` | ✅ | `'milestone'` | 类型标识,必须设为 'milestone' |
|
|
829
|
+
| `icon` | `string` | - | `'diamond'` | 里程碑图标,可选值:'diamond', 'flag', 'star', 'rocket' 等 |
|
|
830
|
+
| `description` | `string` | - | - | 里程碑描述 |
|
|
729
831
|
|
|
730
832
|
> **注意**:`milestones` 属性的类型为 `Task[]`,需要确保每个里程碑对象的 `type` 字段设置为 `'milestone'`。
|
|
731
833
|
|
|
732
834
|
#### 里程碑相关属性
|
|
733
835
|
|
|
734
|
-
| 属性名
|
|
735
|
-
|
|
736
|
-
| `milestones`
|
|
737
|
-
| `useDefaultMilestoneDialog` | `boolean` | `true` | 是否使用内置的里程碑编辑对话框(MilestoneDialog)
|
|
836
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
837
|
+
| --------------------------- | --------- | ------ | -------------------------------------------------------- |
|
|
838
|
+
| `milestones` | `Task[]` | `[]` | 里程碑数据数组(类型为 Task[],需确保 type='milestone') |
|
|
839
|
+
| `useDefaultMilestoneDialog` | `boolean` | `true` | 是否使用内置的里程碑编辑对话框(MilestoneDialog) |
|
|
738
840
|
|
|
739
841
|
**配置说明**:
|
|
842
|
+
|
|
740
843
|
- **默认模式**:`useDefaultMilestoneDialog=true`(默认),双击里程碑自动打开内置 MilestoneDialog
|
|
741
844
|
- **禁用编辑器**:`useDefaultMilestoneDialog=false`,双击里程碑无反应(组件不打开任何编辑器)
|
|
742
845
|
- **自定义编辑器**:可以监听 `onMilestoneDoubleClick` 回调或相关事件,实现自定义编辑逻辑
|
|
743
846
|
|
|
744
847
|
> **💡 里程碑与任务的区别**:
|
|
848
|
+
>
|
|
745
849
|
> - 里程碑数据通过 `milestones` 属性独立管理,与 `tasks` 分开
|
|
746
850
|
> - 里程碑对象的 `type` 字段必须设置为 `'milestone'`
|
|
747
851
|
> - 里程碑不支持子任务、依赖关系等复杂结构
|
|
@@ -751,20 +855,20 @@ const handleTaskAdded = (e) => {
|
|
|
751
855
|
|
|
752
856
|
> **⚠️ 已废弃**:请使用新的事件驱动 API(见下方"里程碑事件"章节)
|
|
753
857
|
|
|
754
|
-
|
|
755
858
|
#### 里程碑事件
|
|
756
859
|
|
|
757
860
|
> **💡 事件驱动架构**:里程碑管理采用事件驱动设计,推荐使用事件 API 替代回调函数。
|
|
758
861
|
|
|
759
|
-
| 事件名
|
|
760
|
-
|
|
761
|
-
| `add-milestone`
|
|
762
|
-
| `milestone-saved`
|
|
763
|
-
| `milestone-deleted`
|
|
764
|
-
| `milestone-icon-changed` | `{ milestoneId: number, icon: string }` | 里程碑图标变更后
|
|
765
|
-
| `milestone-drag-end`
|
|
862
|
+
| 事件名 | 参数 | 触发时机 | 说明 |
|
|
863
|
+
| ------------------------ | --------------------------------------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
|
864
|
+
| `add-milestone` | - | 点击工具栏"添加里程碑"按钮时 | 可用于自定义新增里程碑逻辑。如 `useDefaultMilestoneDialog=true`,组件会自动打开内置 MilestoneDialog |
|
|
865
|
+
| `milestone-saved` | `(milestone: Task) => void` | 里程碑保存后(新增或编辑) | 通过内置 MilestoneDialog 保存里程碑后触发。**注意**:组件已自动更新 `milestones` 数据,外部只需监听此事件做额外处理(如调用 API 保存) |
|
|
866
|
+
| `milestone-deleted` | `{ milestoneId: number }` | 里程碑删除后 | 通过内置 MilestoneDialog 删除里程碑后触发。**注意**:组件已自动更新 `milestones` 数据,外部只需监听此事件做额外处理 |
|
|
867
|
+
| `milestone-icon-changed` | `{ milestoneId: number, icon: string }` | 里程碑图标变更后 | 通过内置 MilestoneDialog 修改图标后触发 |
|
|
868
|
+
| `milestone-drag-end` | `(milestone: Task) => void` | 拖拽里程碑结束时 | 里程碑日期已更新。**注意**:组件已自动更新 `milestones` 数据 |
|
|
766
869
|
|
|
767
870
|
**数据同步说明**:
|
|
871
|
+
|
|
768
872
|
- ✅ **组件内部自动更新**:所有里程碑的增删改操作,组件都会自动更新 `props.milestones` 数据
|
|
769
873
|
- ✅ **事件仅做通知**:外部监听事件主要用于:显示提示消息、调用后端 API、更新其他相关数据等
|
|
770
874
|
- ❌ **避免重复操作**:不要在事件处理器中再次修改 `milestones` 数据,否则会导致重复更新
|
|
@@ -776,7 +880,7 @@ const handleTaskAdded = (e) => {
|
|
|
776
880
|
```vue
|
|
777
881
|
<template>
|
|
778
882
|
<div style="height: 600px;">
|
|
779
|
-
<GanttChart
|
|
883
|
+
<GanttChart
|
|
780
884
|
:milestones="milestones"
|
|
781
885
|
@add-milestone="handleAddMilestone"
|
|
782
886
|
@milestone-saved="handleMilestoneSaved"
|
|
@@ -801,15 +905,15 @@ const milestones = ref<Task[]>([
|
|
|
801
905
|
type: 'milestone',
|
|
802
906
|
icon: 'diamond',
|
|
803
907
|
assignee: '项目经理',
|
|
804
|
-
description: '项目正式启动'
|
|
908
|
+
description: '项目正式启动',
|
|
805
909
|
},
|
|
806
910
|
{
|
|
807
911
|
id: 102,
|
|
808
912
|
name: '需求评审',
|
|
809
913
|
startDate: '2025-01-15',
|
|
810
914
|
type: 'milestone',
|
|
811
|
-
icon: 'flag'
|
|
812
|
-
}
|
|
915
|
+
icon: 'flag',
|
|
916
|
+
},
|
|
813
917
|
])
|
|
814
918
|
|
|
815
919
|
// 工具栏"添加里程碑"按钮点击事件
|
|
@@ -857,7 +961,7 @@ const handleMilestoneDrag = (milestone: Task) => {
|
|
|
857
961
|
```vue
|
|
858
962
|
<template>
|
|
859
963
|
<div style="height: 600px;">
|
|
860
|
-
<GanttChart
|
|
964
|
+
<GanttChart
|
|
861
965
|
:milestones="milestones"
|
|
862
966
|
:use-default-milestone-dialog="false"
|
|
863
967
|
@add-milestone="handleAddMilestone"
|
|
@@ -865,7 +969,7 @@ const handleMilestoneDrag = (milestone: Task) => {
|
|
|
865
969
|
@milestone-deleted="handleMilestoneDeleted"
|
|
866
970
|
@milestone-drag-end="handleMilestoneDrag"
|
|
867
971
|
/>
|
|
868
|
-
|
|
972
|
+
|
|
869
973
|
<!-- 自定义里程碑编辑对话框 -->
|
|
870
974
|
<CustomMilestoneDialog
|
|
871
975
|
v-model:visible="customDialogVisible"
|
|
@@ -892,8 +996,8 @@ const milestones = ref<Task[]>([
|
|
|
892
996
|
type: 'milestone',
|
|
893
997
|
icon: 'diamond',
|
|
894
998
|
assignee: '项目经理',
|
|
895
|
-
description: '项目正式启动'
|
|
896
|
-
}
|
|
999
|
+
description: '项目正式启动',
|
|
1000
|
+
},
|
|
897
1001
|
])
|
|
898
1002
|
|
|
899
1003
|
const customDialogVisible = ref(false)
|
|
@@ -923,10 +1027,10 @@ const handleCustomDialogSave = (milestone: Task) => {
|
|
|
923
1027
|
const newMilestone = {
|
|
924
1028
|
...milestone,
|
|
925
1029
|
id: Date.now(), // 生成新 ID
|
|
926
|
-
type: 'milestone'
|
|
1030
|
+
type: 'milestone',
|
|
927
1031
|
}
|
|
928
1032
|
milestones.value.push(newMilestone)
|
|
929
|
-
|
|
1033
|
+
|
|
930
1034
|
// 调用后端 API 保存
|
|
931
1035
|
// await api.createMilestone(newMilestone)
|
|
932
1036
|
} else {
|
|
@@ -935,11 +1039,11 @@ const handleCustomDialogSave = (milestone: Task) => {
|
|
|
935
1039
|
if (index !== -1) {
|
|
936
1040
|
milestones.value[index] = { ...milestone }
|
|
937
1041
|
}
|
|
938
|
-
|
|
1042
|
+
|
|
939
1043
|
// 调用后端 API 更新
|
|
940
1044
|
// await api.updateMilestone(milestone)
|
|
941
1045
|
}
|
|
942
|
-
|
|
1046
|
+
|
|
943
1047
|
customDialogVisible.value = false
|
|
944
1048
|
}
|
|
945
1049
|
|
|
@@ -949,10 +1053,10 @@ const handleCustomDialogDelete = (milestoneId: number) => {
|
|
|
949
1053
|
if (index !== -1) {
|
|
950
1054
|
milestones.value.splice(index, 1)
|
|
951
1055
|
}
|
|
952
|
-
|
|
1056
|
+
|
|
953
1057
|
// 调用后端 API 删除
|
|
954
1058
|
// await api.deleteMilestone(milestoneId)
|
|
955
|
-
|
|
1059
|
+
|
|
956
1060
|
customDialogVisible.value = false
|
|
957
1061
|
}
|
|
958
1062
|
|
|
@@ -989,7 +1093,7 @@ const handleMilestoneDrag = (milestone: Task) => {
|
|
|
989
1093
|
<el-form-item label="里程碑名称">
|
|
990
1094
|
<el-input v-model="form.name" placeholder="请输入里程碑名称" />
|
|
991
1095
|
</el-form-item>
|
|
992
|
-
|
|
1096
|
+
|
|
993
1097
|
<el-form-item label="日期">
|
|
994
1098
|
<el-date-picker
|
|
995
1099
|
v-model="form.startDate"
|
|
@@ -998,11 +1102,11 @@ const handleMilestoneDrag = (milestone: Task) => {
|
|
|
998
1102
|
value-format="YYYY-MM-DD"
|
|
999
1103
|
/>
|
|
1000
1104
|
</el-form-item>
|
|
1001
|
-
|
|
1105
|
+
|
|
1002
1106
|
<el-form-item label="负责人">
|
|
1003
1107
|
<el-input v-model="form.assignee" placeholder="请输入负责人" />
|
|
1004
1108
|
</el-form-item>
|
|
1005
|
-
|
|
1109
|
+
|
|
1006
1110
|
<el-form-item label="图标">
|
|
1007
1111
|
<el-select v-model="form.icon" placeholder="选择图标">
|
|
1008
1112
|
<el-option label="钻石" value="diamond" />
|
|
@@ -1011,22 +1115,15 @@ const handleMilestoneDrag = (milestone: Task) => {
|
|
|
1011
1115
|
<el-option label="火箭" value="rocket" />
|
|
1012
1116
|
</el-select>
|
|
1013
1117
|
</el-form-item>
|
|
1014
|
-
|
|
1118
|
+
|
|
1015
1119
|
<el-form-item label="描述">
|
|
1016
|
-
<el-input
|
|
1017
|
-
v-model="form.description"
|
|
1018
|
-
type="textarea"
|
|
1019
|
-
:rows="3"
|
|
1020
|
-
placeholder="请输入描述"
|
|
1021
|
-
/>
|
|
1120
|
+
<el-input v-model="form.description" type="textarea" :rows="3" placeholder="请输入描述" />
|
|
1022
1121
|
</el-form-item>
|
|
1023
1122
|
</el-form>
|
|
1024
|
-
|
|
1123
|
+
|
|
1025
1124
|
<template #footer>
|
|
1026
1125
|
<div class="dialog-footer">
|
|
1027
|
-
<el-button v-if="!isNew" type="danger" @click="handleDelete">
|
|
1028
|
-
删除
|
|
1029
|
-
</el-button>
|
|
1126
|
+
<el-button v-if="!isNew" type="danger" @click="handleDelete"> 删除 </el-button>
|
|
1030
1127
|
<el-button @click="handleClose">取消</el-button>
|
|
1031
1128
|
<el-button type="primary" @click="handleSave">保存</el-button>
|
|
1032
1129
|
</div>
|
|
@@ -1059,31 +1156,34 @@ const form = ref({
|
|
|
1059
1156
|
assignee: '',
|
|
1060
1157
|
icon: 'diamond',
|
|
1061
1158
|
description: '',
|
|
1062
|
-
type: 'milestone'
|
|
1159
|
+
type: 'milestone',
|
|
1063
1160
|
})
|
|
1064
1161
|
|
|
1065
|
-
watch(
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1162
|
+
watch(
|
|
1163
|
+
() => props.visible,
|
|
1164
|
+
val => {
|
|
1165
|
+
dialogVisible.value = val
|
|
1166
|
+
if (val) {
|
|
1167
|
+
if (props.milestone) {
|
|
1168
|
+
// 编辑模式,填充数据
|
|
1169
|
+
form.value = { ...props.milestone }
|
|
1170
|
+
} else {
|
|
1171
|
+
// 新增模式,重置表单
|
|
1172
|
+
form.value = {
|
|
1173
|
+
id: 0,
|
|
1174
|
+
name: '',
|
|
1175
|
+
startDate: new Date().toISOString().split('T')[0],
|
|
1176
|
+
assignee: '',
|
|
1177
|
+
icon: 'diamond',
|
|
1178
|
+
description: '',
|
|
1179
|
+
type: 'milestone',
|
|
1180
|
+
}
|
|
1081
1181
|
}
|
|
1082
1182
|
}
|
|
1083
1183
|
}
|
|
1084
|
-
|
|
1184
|
+
)
|
|
1085
1185
|
|
|
1086
|
-
watch(dialogVisible,
|
|
1186
|
+
watch(dialogVisible, val => {
|
|
1087
1187
|
emit('update:visible', val)
|
|
1088
1188
|
})
|
|
1089
1189
|
|
|
@@ -1108,6 +1208,7 @@ const handleDelete = () => {
|
|
|
1108
1208
|
```
|
|
1109
1209
|
|
|
1110
1210
|
> **💡 自定义对话框说明**:
|
|
1211
|
+
>
|
|
1111
1212
|
> - 设置 `use-default-milestone-dialog="false"` 禁用内置对话框
|
|
1112
1213
|
> - 监听 `@add-milestone` 事件打开自定义对话框
|
|
1113
1214
|
> - 需要手动管理 `milestones` 数组的增删改
|
|
@@ -1128,20 +1229,20 @@ const handleDelete = () => {
|
|
|
1128
1229
|
|
|
1129
1230
|
**类型定义:**
|
|
1130
1231
|
|
|
1131
|
-
| 字段名
|
|
1132
|
-
|
|
1133
|
-
| `showAddTask`
|
|
1134
|
-
| `showAddMilestone`
|
|
1135
|
-
| `showTodayLocate`
|
|
1136
|
-
| `showExportCsv`
|
|
1137
|
-
| `showExportPdf`
|
|
1138
|
-
| `showLanguage`
|
|
1139
|
-
| `showTheme`
|
|
1140
|
-
| `showFullscreen`
|
|
1141
|
-
| `showTimeScale`
|
|
1232
|
+
| 字段名 | 类型 | 默认值 | 说明 |
|
|
1233
|
+
| --------------------- | ----------------- | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
|
|
1234
|
+
| `showAddTask` | `boolean` | `true` | 显示"添加任务"按钮 |
|
|
1235
|
+
| `showAddMilestone` | `boolean` | `true` | 显示"添加里程碑"按钮 |
|
|
1236
|
+
| `showTodayLocate` | `boolean` | `true` | 显示"定位到今天"按钮 |
|
|
1237
|
+
| `showExportCsv` | `boolean` | `true` | 显示"导出 CSV"按钮 |
|
|
1238
|
+
| `showExportPdf` | `boolean` | `true` | 显示"导出 PDF"按钮 |
|
|
1239
|
+
| `showLanguage` | `boolean` | `true` | 显示"语言切换"按钮(中/英文) |
|
|
1240
|
+
| `showTheme` | `boolean` | `true` | 显示"主题切换"按钮(亮色/暗色) |
|
|
1241
|
+
| `showFullscreen` | `boolean` | `true` | 显示"全屏"按钮 |
|
|
1242
|
+
| `showTimeScale` | `boolean` | `true` | 显示时间刻度按钮组(控制整组按钮的显隐) |
|
|
1142
1243
|
| `timeScaleDimensions` | `TimelineScale[]` | `['hour', 'day', 'week', 'month', 'quarter', 'year']` | 设置时间刻度按钮组要显示的维度,可选值:`'hour'`、`'day'`、`'week'`、`'month'`、`'quarter'`、`'year'` |
|
|
1143
|
-
| `defaultTimeScale`
|
|
1144
|
-
| `showExpandCollapse`
|
|
1244
|
+
| `defaultTimeScale` | `TimelineScale` | `'week'` | 默认选中的时间刻度 |
|
|
1245
|
+
| `showExpandCollapse` | `boolean` | `true` | 显示"全部展开/折叠"按钮(用于父子任务树形结构) |
|
|
1145
1246
|
|
|
1146
1247
|
**TimelineScale 类型说明:**
|
|
1147
1248
|
|
|
@@ -1151,22 +1252,19 @@ type TimelineScale = 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year'
|
|
|
1151
1252
|
// 也可以使用常量形式
|
|
1152
1253
|
import { TimelineScale } from 'jordium-gantt-vue3'
|
|
1153
1254
|
|
|
1154
|
-
TimelineScale.HOUR
|
|
1155
|
-
TimelineScale.DAY
|
|
1156
|
-
TimelineScale.WEEK
|
|
1157
|
-
TimelineScale.MONTH
|
|
1255
|
+
TimelineScale.HOUR // 'hour' - 小时视图
|
|
1256
|
+
TimelineScale.DAY // 'day' - 日视图
|
|
1257
|
+
TimelineScale.WEEK // 'week' - 周视图
|
|
1258
|
+
TimelineScale.MONTH // 'month' - 月视图
|
|
1158
1259
|
TimelineScale.QUARTER // 'quarter' - 季度视图
|
|
1159
|
-
TimelineScale.YEAR
|
|
1260
|
+
TimelineScale.YEAR // 'year' - 年视图
|
|
1160
1261
|
```
|
|
1161
1262
|
|
|
1162
1263
|
**示例1:完整配置(显示所有功能)**
|
|
1163
1264
|
|
|
1164
1265
|
```vue
|
|
1165
1266
|
<template>
|
|
1166
|
-
<GanttChart
|
|
1167
|
-
:tasks="tasks"
|
|
1168
|
-
:toolbar-config="toolbarConfig"
|
|
1169
|
-
/>
|
|
1267
|
+
<GanttChart :tasks="tasks" :toolbar-config="toolbarConfig" />
|
|
1170
1268
|
</template>
|
|
1171
1269
|
|
|
1172
1270
|
<script setup lang="ts">
|
|
@@ -1175,20 +1273,26 @@ import 'jordium-gantt-vue3/dist/assets/jordium-gantt-vue3.css'
|
|
|
1175
1273
|
import type { ToolbarConfig } from 'jordium-gantt-vue3'
|
|
1176
1274
|
|
|
1177
1275
|
const toolbarConfig: ToolbarConfig = {
|
|
1178
|
-
showAddTask: true,
|
|
1179
|
-
showAddMilestone: true,
|
|
1180
|
-
showTodayLocate: true,
|
|
1181
|
-
showExportCsv: true,
|
|
1182
|
-
showExportPdf: true,
|
|
1183
|
-
showLanguage: true,
|
|
1184
|
-
showTheme: true,
|
|
1185
|
-
showFullscreen: true,
|
|
1186
|
-
showTimeScale: true,
|
|
1187
|
-
timeScaleDimensions: [
|
|
1188
|
-
|
|
1276
|
+
showAddTask: true, // 显示添加任务按钮
|
|
1277
|
+
showAddMilestone: true, // 显示添加里程碑按钮
|
|
1278
|
+
showTodayLocate: true, // 显示定位到今天按钮
|
|
1279
|
+
showExportCsv: true, // 显示导出CSV按钮
|
|
1280
|
+
showExportPdf: true, // 显示导出PDF按钮
|
|
1281
|
+
showLanguage: true, // 显示语言切换按钮
|
|
1282
|
+
showTheme: true, // 显示主题切换按钮
|
|
1283
|
+
showFullscreen: true, // 显示全屏按钮
|
|
1284
|
+
showTimeScale: true, // 显示时间刻度按钮组
|
|
1285
|
+
timeScaleDimensions: [
|
|
1286
|
+
// 显示所有时间刻度维度
|
|
1287
|
+
'hour',
|
|
1288
|
+
'day',
|
|
1289
|
+
'week',
|
|
1290
|
+
'month',
|
|
1291
|
+
'quarter',
|
|
1292
|
+
'year',
|
|
1189
1293
|
],
|
|
1190
|
-
defaultTimeScale: 'week',
|
|
1191
|
-
showExpandCollapse: true
|
|
1294
|
+
defaultTimeScale: 'week', // 默认选中周视图
|
|
1295
|
+
showExpandCollapse: true, // 显示展开/折叠按钮
|
|
1192
1296
|
}
|
|
1193
1297
|
</script>
|
|
1194
1298
|
```
|
|
@@ -1200,20 +1304,23 @@ const toolbarConfig: ToolbarConfig = {
|
|
|
1200
1304
|
import type { ToolbarConfig } from 'jordium-gantt-vue3'
|
|
1201
1305
|
|
|
1202
1306
|
const toolbarConfig: ToolbarConfig = {
|
|
1203
|
-
showAddTask: true,
|
|
1204
|
-
showAddMilestone: true,
|
|
1205
|
-
showTodayLocate: true,
|
|
1206
|
-
showExportCsv: false,
|
|
1207
|
-
showExportPdf: false,
|
|
1208
|
-
showLanguage: false,
|
|
1209
|
-
showTheme: true,
|
|
1210
|
-
showFullscreen: true,
|
|
1211
|
-
showTimeScale: true,
|
|
1212
|
-
timeScaleDimensions: [
|
|
1213
|
-
|
|
1307
|
+
showAddTask: true, // 保留添加任务
|
|
1308
|
+
showAddMilestone: true, // 保留添加里程碑
|
|
1309
|
+
showTodayLocate: true, // 保留定位今天
|
|
1310
|
+
showExportCsv: false, // 隐藏导出CSV
|
|
1311
|
+
showExportPdf: false, // 隐藏导出PDF
|
|
1312
|
+
showLanguage: false, // 隐藏语言切换(固定使用一种语言)
|
|
1313
|
+
showTheme: true, // 保留主题切换
|
|
1314
|
+
showFullscreen: true, // 保留全屏
|
|
1315
|
+
showTimeScale: true, // 显示时间刻度
|
|
1316
|
+
timeScaleDimensions: [
|
|
1317
|
+
// 只显示日/周/月三种刻度
|
|
1318
|
+
'day',
|
|
1319
|
+
'week',
|
|
1320
|
+
'month',
|
|
1214
1321
|
],
|
|
1215
|
-
defaultTimeScale: 'week',
|
|
1216
|
-
showExpandCollapse: true
|
|
1322
|
+
defaultTimeScale: 'week', // 默认周视图
|
|
1323
|
+
showExpandCollapse: true, // 保留展开/折叠
|
|
1217
1324
|
}
|
|
1218
1325
|
</script>
|
|
1219
1326
|
```
|
|
@@ -1231,9 +1338,9 @@ const toolbarConfig: ToolbarConfig = {
|
|
|
1231
1338
|
TimelineScale.DAY,
|
|
1232
1339
|
TimelineScale.WEEK,
|
|
1233
1340
|
TimelineScale.MONTH,
|
|
1234
|
-
TimelineScale.QUARTER
|
|
1341
|
+
TimelineScale.QUARTER,
|
|
1235
1342
|
],
|
|
1236
|
-
defaultTimeScale: TimelineScale.MONTH
|
|
1343
|
+
defaultTimeScale: TimelineScale.MONTH, // 默认月视图
|
|
1237
1344
|
}
|
|
1238
1345
|
</script>
|
|
1239
1346
|
```
|
|
@@ -1245,23 +1352,24 @@ const toolbarConfig: ToolbarConfig = {
|
|
|
1245
1352
|
import type { ToolbarConfig } from 'jordium-gantt-vue3'
|
|
1246
1353
|
|
|
1247
1354
|
const toolbarConfig: ToolbarConfig = {
|
|
1248
|
-
showAddTask: false,
|
|
1355
|
+
showAddTask: false, // 隐藏所有编辑按钮
|
|
1249
1356
|
showAddMilestone: false,
|
|
1250
|
-
showTodayLocate: true,
|
|
1357
|
+
showTodayLocate: true, // 只保留导航功能
|
|
1251
1358
|
showExportCsv: false,
|
|
1252
1359
|
showExportPdf: false,
|
|
1253
1360
|
showLanguage: false,
|
|
1254
1361
|
showTheme: false,
|
|
1255
1362
|
showFullscreen: false,
|
|
1256
|
-
showTimeScale: true,
|
|
1363
|
+
showTimeScale: true, // 保留时间刻度切换
|
|
1257
1364
|
timeScaleDimensions: ['week', 'month'],
|
|
1258
1365
|
defaultTimeScale: 'month',
|
|
1259
|
-
showExpandCollapse: false
|
|
1366
|
+
showExpandCollapse: false, // 隐藏展开/折叠
|
|
1260
1367
|
}
|
|
1261
1368
|
</script>
|
|
1262
1369
|
```
|
|
1263
1370
|
|
|
1264
1371
|
> **💡 配置建议**:
|
|
1372
|
+
>
|
|
1265
1373
|
> - **默认配置**:不传 `toolbar-config` 时,所有按钮默认显示
|
|
1266
1374
|
> - **按需显示**:根据业务需求隐藏不需要的功能按钮
|
|
1267
1375
|
> - **时间刻度**:`timeScaleDimensions` 控制显示哪些时间维度,建议选择 2-4 个常用维度
|
|
@@ -1273,32 +1381,29 @@ const toolbarConfig: ToolbarConfig = {
|
|
|
1273
1381
|
|
|
1274
1382
|
**类型定义:**
|
|
1275
1383
|
|
|
1276
|
-
| 字段名
|
|
1277
|
-
|
|
1278
|
-
| `columns`
|
|
1279
|
-
| `showAllColumns` | `boolean`
|
|
1280
|
-
| `defaultWidth`
|
|
1281
|
-
| `minWidth`
|
|
1282
|
-
| `maxWidth`
|
|
1384
|
+
| 字段名 | 类型 | 默认值 | 说明 |
|
|
1385
|
+
| ---------------- | ------------------------ | ------- | ------------------------------------------------------------------------------ |
|
|
1386
|
+
| `columns` | `TaskListColumnConfig[]` | 默认8列 | 任务列表的列配置数组,定义显示哪些列及其属性 |
|
|
1387
|
+
| `showAllColumns` | `boolean` | `true` | 是否显示所有列。`true` 时忽略 `columns` 中的 `visible` 设置 |
|
|
1388
|
+
| `defaultWidth` | `number \| string` | `320` | 默认展开宽度。支持像素数字(如 `320`)或百分比字符串(如 `'30%'`) |
|
|
1389
|
+
| `minWidth` | `number \| string` | `280` | 最小宽度。支持像素数字(如 `280`)或百分比字符串(如 `'20%'`)。不能小于 280px |
|
|
1390
|
+
| `maxWidth` | `number \| string` | `1160` | 最大宽度。支持像素数字(如 `1160`)或百分比字符串(如 `'80%'`) |
|
|
1283
1391
|
|
|
1284
1392
|
**TaskListColumnConfig 类型定义:**
|
|
1285
1393
|
|
|
1286
|
-
| 字段名
|
|
1287
|
-
|
|
1288
|
-
| `key`
|
|
1289
|
-
| `label`
|
|
1290
|
-
| `cssClass` | `string`
|
|
1291
|
-
| `width`
|
|
1292
|
-
| `visible`
|
|
1394
|
+
| 字段名 | 类型 | 必填 | 说明 |
|
|
1395
|
+
| ---------- | --------- | ---- | ---------------------------------------------------------------- |
|
|
1396
|
+
| `key` | `string` | ✅ | 列的唯一标识符,用于访问 Task 对象中的字段,也用于国际化 |
|
|
1397
|
+
| `label` | `string` | - | 列的显示标签(表头文字) |
|
|
1398
|
+
| `cssClass` | `string` | - | 自定义 CSS 类名 |
|
|
1399
|
+
| `width` | `number` | - | 列宽度(单位:像素) |
|
|
1400
|
+
| `visible` | `boolean` | - | 是否显示该列,默认 `true`。当 `showAllColumns=true` 时此设置无效 |
|
|
1293
1401
|
|
|
1294
1402
|
**示例1:基础配置(调整宽度)**
|
|
1295
1403
|
|
|
1296
1404
|
```vue
|
|
1297
1405
|
<template>
|
|
1298
|
-
<GanttChart
|
|
1299
|
-
:tasks="tasks"
|
|
1300
|
-
:task-list-config="taskListConfig"
|
|
1301
|
-
/>
|
|
1406
|
+
<GanttChart :tasks="tasks" :task-list-config="taskListConfig" />
|
|
1302
1407
|
</template>
|
|
1303
1408
|
|
|
1304
1409
|
<script setup lang="ts">
|
|
@@ -1307,9 +1412,9 @@ import 'jordium-gantt-vue3/dist/assets/jordium-gantt-vue3.css'
|
|
|
1307
1412
|
import type { TaskListConfig } from 'jordium-gantt-vue3'
|
|
1308
1413
|
|
|
1309
1414
|
const taskListConfig: TaskListConfig = {
|
|
1310
|
-
defaultWidth: 450,
|
|
1311
|
-
minWidth: 300,
|
|
1312
|
-
maxWidth: 1200,
|
|
1415
|
+
defaultWidth: 450, // 默认宽度450px(比默认值320px更宽)
|
|
1416
|
+
minWidth: 300, // 最小宽度300px
|
|
1417
|
+
maxWidth: 1200, // 最大宽度1200px
|
|
1313
1418
|
}
|
|
1314
1419
|
</script>
|
|
1315
1420
|
```
|
|
@@ -1318,10 +1423,7 @@ const taskListConfig: TaskListConfig = {
|
|
|
1318
1423
|
|
|
1319
1424
|
```vue
|
|
1320
1425
|
<template>
|
|
1321
|
-
<GanttChart
|
|
1322
|
-
:tasks="tasks"
|
|
1323
|
-
:task-list-config="taskListConfig"
|
|
1324
|
-
/>
|
|
1426
|
+
<GanttChart :tasks="tasks" :task-list-config="taskListConfig" />
|
|
1325
1427
|
</template>
|
|
1326
1428
|
|
|
1327
1429
|
<script setup lang="ts">
|
|
@@ -1330,9 +1432,9 @@ import 'jordium-gantt-vue3/dist/assets/jordium-gantt-vue3.css'
|
|
|
1330
1432
|
import type { TaskListConfig } from 'jordium-gantt-vue3'
|
|
1331
1433
|
|
|
1332
1434
|
const taskListConfig: TaskListConfig = {
|
|
1333
|
-
defaultWidth: '25%',
|
|
1334
|
-
minWidth: '15%',
|
|
1335
|
-
maxWidth: '60%',
|
|
1435
|
+
defaultWidth: '25%', // 默认占容器宽度的25%
|
|
1436
|
+
minWidth: '15%', // 最小占15%
|
|
1437
|
+
maxWidth: '60%', // 最大占60%
|
|
1336
1438
|
}
|
|
1337
1439
|
</script>
|
|
1338
1440
|
```
|
|
@@ -1343,10 +1445,7 @@ const taskListConfig: TaskListConfig = {
|
|
|
1343
1445
|
|
|
1344
1446
|
```vue
|
|
1345
1447
|
<template>
|
|
1346
|
-
<GanttChart
|
|
1347
|
-
:tasks="tasks"
|
|
1348
|
-
:task-list-config="taskListConfig"
|
|
1349
|
-
/>
|
|
1448
|
+
<GanttChart :tasks="tasks" :task-list-config="taskListConfig" />
|
|
1350
1449
|
</template>
|
|
1351
1450
|
|
|
1352
1451
|
<script setup lang="ts">
|
|
@@ -1394,7 +1493,7 @@ const taskListConfig: TaskListConfig = {
|
|
|
1394
1493
|
defaultWidth: 350,
|
|
1395
1494
|
minWidth: 280,
|
|
1396
1495
|
maxWidth: 500,
|
|
1397
|
-
showAllColumns: false,
|
|
1496
|
+
showAllColumns: false, // 只显示 visible=true 的列
|
|
1398
1497
|
}
|
|
1399
1498
|
</script>
|
|
1400
1499
|
```
|
|
@@ -1410,9 +1509,9 @@ import type { TaskListConfig, TaskListColumnConfig } from 'jordium-gantt-vue3'
|
|
|
1410
1509
|
// 定义包含自定义列的配置
|
|
1411
1510
|
const columns: TaskListColumnConfig[] = [
|
|
1412
1511
|
{ key: 'name', label: '任务名称', visible: true },
|
|
1413
|
-
{ key: 'priority', label: '优先级', width: 80, visible: true },
|
|
1414
|
-
{ key: 'department', label: '部门', width: 100, visible: true },
|
|
1415
|
-
{ key: 'status', label: '状态', width: 80, visible: true },
|
|
1512
|
+
{ key: 'priority', label: '优先级', width: 80, visible: true }, // 自定义列
|
|
1513
|
+
{ key: 'department', label: '部门', width: 100, visible: true }, // 自定义列
|
|
1514
|
+
{ key: 'status', label: '状态', width: 80, visible: true }, // 自定义列
|
|
1416
1515
|
{ key: 'assignee', label: '负责人', visible: true },
|
|
1417
1516
|
{ key: 'startDate', label: '开始日期', visible: true },
|
|
1418
1517
|
{ key: 'endDate', label: '结束日期', visible: true },
|
|
@@ -1431,10 +1530,7 @@ const taskListConfig: TaskListConfig = {
|
|
|
1431
1530
|
|
|
1432
1531
|
```vue
|
|
1433
1532
|
<template>
|
|
1434
|
-
<GanttChart
|
|
1435
|
-
:tasks="tasks"
|
|
1436
|
-
:task-list-config="taskListConfig"
|
|
1437
|
-
/>
|
|
1533
|
+
<GanttChart :tasks="tasks" :task-list-config="taskListConfig" />
|
|
1438
1534
|
</template>
|
|
1439
1535
|
|
|
1440
1536
|
<script setup lang="ts">
|
|
@@ -1473,6 +1569,7 @@ const taskListConfig = computed<TaskListConfig>(() => ({
|
|
|
1473
1569
|
```
|
|
1474
1570
|
|
|
1475
1571
|
> **💡 配置说明**:
|
|
1572
|
+
>
|
|
1476
1573
|
> - **默认行为**:不传 `task-list-config` 时,显示所有 8 个默认列,宽度为 320px
|
|
1477
1574
|
> - **宽度单位**:支持像素(`number`)和百分比(`string`,如 `'30%'`)两种方式
|
|
1478
1575
|
> - **百分比计算**:基于甘特图容器的总宽度,响应式调整
|
|
@@ -1488,17 +1585,18 @@ const taskListConfig = computed<TaskListConfig>(() => ({
|
|
|
1488
1585
|
|
|
1489
1586
|
**配置字段:**
|
|
1490
1587
|
|
|
1491
|
-
| 字段名
|
|
1492
|
-
|
|
1493
|
-
| `showAvatar`
|
|
1494
|
-
| `showTitle`
|
|
1495
|
-
| `showProgress`
|
|
1496
|
-
| `dragThreshold`
|
|
1497
|
-
| `resizeHandleWidth` | `number`
|
|
1498
|
-
| `enableDragDelay`
|
|
1499
|
-
| `dragDelayTime`
|
|
1588
|
+
| 字段名 | 类型 | 默认值 | 说明 |
|
|
1589
|
+
| ------------------- | --------- | ------- | ------------------------------- |
|
|
1590
|
+
| `showAvatar` | `boolean` | `true` | 是否展示头像 |
|
|
1591
|
+
| `showTitle` | `boolean` | `true` | 是否展示标题文字 |
|
|
1592
|
+
| `showProgress` | `boolean` | `true` | 是否展示进度文字 |
|
|
1593
|
+
| `dragThreshold` | `number` | `5` | 拖拽触发阈值(像素) |
|
|
1594
|
+
| `resizeHandleWidth` | `number` | `5` | 拉伸手柄宽度(像素),最大 15px |
|
|
1595
|
+
| `enableDragDelay` | `boolean` | `false` | 是否启用拖拽延迟(防止误触) |
|
|
1596
|
+
| `dragDelayTime` | `number` | `150` | 拖拽延迟时间(毫秒) |
|
|
1500
1597
|
|
|
1501
1598
|
> **💡 编辑权限控制**:
|
|
1599
|
+
>
|
|
1502
1600
|
> - **全局控制**:使用 `<GanttChart :allow-drag-and-resize="false" />` 禁用所有任务的拖拽/拉伸
|
|
1503
1601
|
> - **单个任务控制**:设置任务对象的 `isEditable: false` 属性单独控制某个任务
|
|
1504
1602
|
|
|
@@ -1506,10 +1604,7 @@ const taskListConfig = computed<TaskListConfig>(() => ({
|
|
|
1506
1604
|
|
|
1507
1605
|
```vue
|
|
1508
1606
|
<template>
|
|
1509
|
-
<GanttChart
|
|
1510
|
-
:tasks="tasks"
|
|
1511
|
-
:task-bar-config="taskBarConfig"
|
|
1512
|
-
/>
|
|
1607
|
+
<GanttChart :tasks="tasks" :task-bar-config="taskBarConfig" />
|
|
1513
1608
|
</template>
|
|
1514
1609
|
|
|
1515
1610
|
<script setup lang="ts">
|
|
@@ -1535,10 +1630,7 @@ const taskBarConfig: TaskBarConfig = {
|
|
|
1535
1630
|
|
|
1536
1631
|
```vue
|
|
1537
1632
|
<template>
|
|
1538
|
-
<GanttChart
|
|
1539
|
-
:tasks="tasks"
|
|
1540
|
-
:allow-drag-and-resize="false"
|
|
1541
|
-
/>
|
|
1633
|
+
<GanttChart :tasks="tasks" :allow-drag-and-resize="false" />
|
|
1542
1634
|
</template>
|
|
1543
1635
|
```
|
|
1544
1636
|
|
|
@@ -1612,6 +1704,7 @@ const taskBarConfig = computed<TaskBarConfig>(() => ({
|
|
|
1612
1704
|
**核心设计思路:**
|
|
1613
1705
|
|
|
1614
1706
|
1. **基础缓冲机制**:在任务的实际时间范围基础上,根据不同视图添加固定的缓冲区
|
|
1707
|
+
|
|
1615
1708
|
- 小时视图:任务范围前后各 ±1 天
|
|
1616
1709
|
- 日视图:任务范围前后各 ±30 天
|
|
1617
1710
|
- 周视图:任务范围前后各 ±8 周(约2个月)
|
|
@@ -1620,10 +1713,12 @@ const taskBarConfig = computed<TaskBarConfig>(() => ({
|
|
|
1620
1713
|
- 年视图:任务范围前后各 ±1 年
|
|
1621
1714
|
|
|
1622
1715
|
2. **容器宽度适配**:基础缓冲后,如果计算出的时间线宽度小于容器宽度,会自动扩展范围
|
|
1716
|
+
|
|
1623
1717
|
- 计算容器需要的时间单位数(天/周/月/季度/年)
|
|
1624
1718
|
- 在基础范围两侧**对称扩展**,确保时间线填充满容器
|
|
1625
1719
|
|
|
1626
1720
|
3. **空数据处理**:当没有任务数据时,根据容器宽度和时间刻度计算合理的时间范围
|
|
1721
|
+
|
|
1627
1722
|
- 以当前日期为中心
|
|
1628
1723
|
- 根据容器宽度动态计算需要显示的时间跨度
|
|
1629
1724
|
- 确保最小显示范围(如日视图至少60天,周视图至少20周等)
|
|
@@ -1634,23 +1729,25 @@ const taskBarConfig = computed<TaskBarConfig>(() => ({
|
|
|
1634
1729
|
|
|
1635
1730
|
**各视图计算模式对照表:**
|
|
1636
1731
|
|
|
1637
|
-
| 视图
|
|
1638
|
-
|
|
1639
|
-
| 小时视图 | 30px/时
|
|
1640
|
-
| 日视图
|
|
1641
|
-
| 周视图
|
|
1642
|
-
| 月视图
|
|
1643
|
-
| 季度视图 | 60px/季度 (240px/年) | ±1年
|
|
1644
|
-
| 年视图
|
|
1732
|
+
| 视图 | 单位宽度 | 基础缓冲 | 空数据最小范围 | 容器自动填充? |
|
|
1733
|
+
| -------- | -------------------- | -------- | -------------- | -------------- |
|
|
1734
|
+
| 小时视图 | 30px/时 | ±1天 | 3天 | ✅ |
|
|
1735
|
+
| 日视图 | 30px/天 | ±30天 | 60天 | ✅ |
|
|
1736
|
+
| 周视图 | 60px/周 | ±2月 | 20周 | ✅ |
|
|
1737
|
+
| 月视图 | 60px/月 | ±1年 | 3年 | ✅ |
|
|
1738
|
+
| 季度视图 | 60px/季度 (240px/年) | ±1年 | 5年 | ✅ |
|
|
1739
|
+
| 年视图 | 360px/年 | ±1年 | 5年 | ✅ |
|
|
1645
1740
|
|
|
1646
1741
|
**实际应用场景:**
|
|
1647
1742
|
|
|
1648
1743
|
- **短期任务**(如1周项目, 分辨率1080):
|
|
1744
|
+
|
|
1649
1745
|
- 不会导致时间线过窄,自动扩展到填充满容器
|
|
1650
1746
|
- 日视图:1周(7天×30px=210px) → 扩展至 ≥1200px(约40天)
|
|
1651
1747
|
- 周视图:1周(60px) → 扩展至 ≥1200px(约20周)
|
|
1652
1748
|
|
|
1653
1749
|
- **长期项目**(如2年项目):
|
|
1750
|
+
|
|
1654
1751
|
- 添加固定缓冲后,自动适配容器
|
|
1655
1752
|
- 月视图:24个月 + 缓冲 → 如需要则扩展至容器宽度
|
|
1656
1753
|
- 季度视图:8个季度 + 缓冲 → 如需要则扩展至容器宽度
|
|
@@ -1662,6 +1759,7 @@ const taskBarConfig = computed<TaskBarConfig>(() => ({
|
|
|
1662
1759
|
- 季度/年视图:显示至少5年
|
|
1663
1760
|
|
|
1664
1761
|
> **💡 自动化优势**:
|
|
1762
|
+
>
|
|
1665
1763
|
> - 无需手动设置 `startDate` 和 `endDate`,组件会自动计算最优范围
|
|
1666
1764
|
> - 响应式容器宽度变化,时间线自动重新计算
|
|
1667
1765
|
> - 不同视图独立优化,切换视图时自动调整到最佳显示效果
|
|
@@ -1676,10 +1774,7 @@ const taskBarConfig = computed<TaskBarConfig>(() => ({
|
|
|
1676
1774
|
|
|
1677
1775
|
```vue
|
|
1678
1776
|
<template>
|
|
1679
|
-
<GanttChart
|
|
1680
|
-
:tasks="tasks"
|
|
1681
|
-
:on-theme-change="handleThemeChange"
|
|
1682
|
-
/>
|
|
1777
|
+
<GanttChart :tasks="tasks" :on-theme-change="handleThemeChange" />
|
|
1683
1778
|
</template>
|
|
1684
1779
|
|
|
1685
1780
|
<script setup lang="ts">
|
|
@@ -1703,21 +1798,21 @@ const handleThemeChange = (isDark: boolean) => {
|
|
|
1703
1798
|
--gantt-success-color: #67c23a;
|
|
1704
1799
|
--gantt-warning-color: #e6a23c;
|
|
1705
1800
|
--gantt-danger-color: #f56c6c;
|
|
1706
|
-
|
|
1801
|
+
|
|
1707
1802
|
/* 背景色 */
|
|
1708
1803
|
--gantt-bg-primary: #ffffff;
|
|
1709
1804
|
--gantt-bg-secondary: #f5f7fa;
|
|
1710
1805
|
--gantt-bg-hover: #ecf5ff;
|
|
1711
|
-
|
|
1806
|
+
|
|
1712
1807
|
/* 文字颜色 */
|
|
1713
1808
|
--gantt-text-primary: #303133;
|
|
1714
1809
|
--gantt-text-secondary: #606266;
|
|
1715
1810
|
--gantt-text-placeholder: #c0c4cc;
|
|
1716
|
-
|
|
1811
|
+
|
|
1717
1812
|
/* 边框颜色 */
|
|
1718
1813
|
--gantt-border-color: #dcdfe6;
|
|
1719
1814
|
--gantt-border-color-light: #e4e7ed;
|
|
1720
|
-
|
|
1815
|
+
|
|
1721
1816
|
/* 任务条颜色 */
|
|
1722
1817
|
--gantt-task-bg: #409eff;
|
|
1723
1818
|
--gantt-task-border: #66b1ff;
|
|
@@ -1729,13 +1824,13 @@ const handleThemeChange = (isDark: boolean) => {
|
|
|
1729
1824
|
--gantt-bg-primary: #1a1a1a;
|
|
1730
1825
|
--gantt-bg-secondary: #2c2c2c;
|
|
1731
1826
|
--gantt-bg-hover: #3a3a3a;
|
|
1732
|
-
|
|
1827
|
+
|
|
1733
1828
|
--gantt-text-primary: #e5e5e5;
|
|
1734
1829
|
--gantt-text-secondary: #b0b0b0;
|
|
1735
|
-
|
|
1830
|
+
|
|
1736
1831
|
--gantt-border-color: #3a3a3a;
|
|
1737
1832
|
--gantt-border-color-light: #4a4a4a;
|
|
1738
|
-
|
|
1833
|
+
|
|
1739
1834
|
--gantt-task-bg: #409eff;
|
|
1740
1835
|
--gantt-task-border: #66b1ff;
|
|
1741
1836
|
--gantt-task-text: #ffffff;
|
|
@@ -1748,10 +1843,7 @@ const handleThemeChange = (isDark: boolean) => {
|
|
|
1748
1843
|
|
|
1749
1844
|
```vue
|
|
1750
1845
|
<template>
|
|
1751
|
-
<GanttChart
|
|
1752
|
-
:tasks="tasks"
|
|
1753
|
-
:on-language-change="handleLanguageChange"
|
|
1754
|
-
/>
|
|
1846
|
+
<GanttChart :tasks="tasks" :on-language-change="handleLanguageChange" />
|
|
1755
1847
|
</template>
|
|
1756
1848
|
|
|
1757
1849
|
<script setup lang="ts">
|
|
@@ -1769,66 +1861,67 @@ const handleLanguageChange = (lang: 'zh-CN' | 'en-US') => {
|
|
|
1769
1861
|
|
|
1770
1862
|
```vue
|
|
1771
1863
|
<template>
|
|
1772
|
-
<GanttChart
|
|
1773
|
-
:tasks="tasks"
|
|
1774
|
-
:locale-messages="customMessages"
|
|
1775
|
-
/>
|
|
1864
|
+
<GanttChart :tasks="tasks" :locale-messages="customMessages" />
|
|
1776
1865
|
</template>
|
|
1777
1866
|
|
|
1778
1867
|
<script setup lang="ts">
|
|
1779
1868
|
const customMessages = {
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1869
|
+
"zh-CN": {
|
|
1870
|
+
// 任务列表相关
|
|
1871
|
+
name: '任务名称(自定义)',
|
|
1872
|
+
startDate: '开始日期',
|
|
1873
|
+
endDate: '结束日期',
|
|
1874
|
+
duration: '工期',
|
|
1875
|
+
progress: '完成度',
|
|
1876
|
+
predecessor: '前置任务',
|
|
1877
|
+
assignee: '负责人',
|
|
1878
|
+
estimatedHours: '预估工时',
|
|
1879
|
+
actualHours: '实际工时'
|
|
1880
|
+
|
|
1881
|
+
// 工具栏相关
|
|
1882
|
+
addTask: '新建任务',
|
|
1883
|
+
addMilestone: '新建里程碑',
|
|
1884
|
+
today: '今天',
|
|
1885
|
+
exportCsv: '导出 CSV',
|
|
1886
|
+
exportPdf: '导出 PDF',
|
|
1887
|
+
fullscreen: '全屏',
|
|
1888
|
+
exitFullscreen: '退出全屏',
|
|
1889
|
+
language: '语言',
|
|
1890
|
+
theme: '主题',
|
|
1891
|
+
expandAll: '全部展开',
|
|
1892
|
+
collapseAll: '全部折叠'
|
|
1893
|
+
|
|
1894
|
+
// 内置任务编辑器相关
|
|
1895
|
+
title: '任务详情',
|
|
1896
|
+
titleEdit: '编辑任务',
|
|
1897
|
+
titleNew: '新建任务',
|
|
1898
|
+
name: '任务名称',
|
|
1899
|
+
startDate: '开始日期',
|
|
1900
|
+
endDate: '结束日期',
|
|
1901
|
+
assignee: '负责人',
|
|
1902
|
+
predecessor: '前置任务',
|
|
1903
|
+
description: '描述',
|
|
1904
|
+
estimatedHours: '预估工时',
|
|
1905
|
+
actualHours: '实际工时',
|
|
1906
|
+
progress: '进度',
|
|
1907
|
+
save: '保存',
|
|
1908
|
+
cancel: '取消',
|
|
1909
|
+
delete: '删除'
|
|
1910
|
+
|
|
1911
|
+
// 其他文本
|
|
1912
|
+
days: '天',
|
|
1913
|
+
hours: '小时',
|
|
1914
|
+
overtime: '超时',
|
|
1915
|
+
overdue: '逾期',
|
|
1916
|
+
// ... 更多自定义翻译
|
|
1917
|
+
},
|
|
1918
|
+
"en-US": {......}
|
|
1827
1919
|
}
|
|
1828
1920
|
</script>
|
|
1829
1921
|
```
|
|
1830
1922
|
|
|
1831
1923
|
> **💡 提示**:
|
|
1924
|
+
>
|
|
1832
1925
|
> - `localeMessages` 采用**深度合并**策略,只需传递需要覆盖的字段即可
|
|
1833
1926
|
> - 支持嵌套对象,如 `taskList.name`、`toolbar.addTask` 等
|
|
1834
1927
|
> - 完整的翻译键请参考组件内置的 `messages['zh-CN']` 对象
|
|
@@ -1845,44 +1938,44 @@ const customMessages = {
|
|
|
1845
1938
|
|
|
1846
1939
|
**插槽参数:**
|
|
1847
1940
|
|
|
1848
|
-
| 参数名 | 类型
|
|
1849
|
-
|
|
1941
|
+
| 参数名 | 类型 | 来源 | 说明 |
|
|
1942
|
+
| ------ | ---------------------------- | ---- | ---------------- |
|
|
1850
1943
|
| `type` | `'task-row'` \| `'task-bar'` | 通用 | 插槽调用位置标识 |
|
|
1851
|
-
| `task` | `Task`
|
|
1944
|
+
| `task` | `Task` | 通用 | 当前任务对象 |
|
|
1852
1945
|
|
|
1853
1946
|
**TaskRow 特有参数(当 `type === 'task-row'` 时):**
|
|
1854
1947
|
|
|
1855
|
-
| 参数名
|
|
1856
|
-
|
|
1857
|
-
| `isRowContent`
|
|
1858
|
-
| `level`
|
|
1859
|
-
| `indent`
|
|
1860
|
-
| `isHovered`
|
|
1861
|
-
| `hoveredTaskId`
|
|
1862
|
-
| `isParent`
|
|
1863
|
-
| `hasChildren`
|
|
1864
|
-
| `collapsed`
|
|
1865
|
-
| `formattedTimer` | `string`
|
|
1866
|
-
| `timerRunning`
|
|
1867
|
-
| `timerElapsed`
|
|
1868
|
-
| `isOvertime`
|
|
1869
|
-
| `overdueDays`
|
|
1870
|
-
| `overtimeText`
|
|
1871
|
-
| `overdueText`
|
|
1872
|
-
| `daysText`
|
|
1873
|
-
| `progressClass`
|
|
1948
|
+
| 参数名 | 类型 | 说明 |
|
|
1949
|
+
| ---------------- | -------------------------------- | ---------------- |
|
|
1950
|
+
| `isRowContent` | `boolean` | 标识为行内容 |
|
|
1951
|
+
| `level` | `number` | 任务层级 |
|
|
1952
|
+
| `indent` | `string` | 缩进样式 |
|
|
1953
|
+
| `isHovered` | `boolean` | 是否悬停 |
|
|
1954
|
+
| `hoveredTaskId` | `number \| null` | 当前悬停任务ID |
|
|
1955
|
+
| `isParent` | `boolean` | 是否为父任务 |
|
|
1956
|
+
| `hasChildren` | `boolean` | 是否有子任务 |
|
|
1957
|
+
| `collapsed` | `boolean` | 是否折叠 |
|
|
1958
|
+
| `formattedTimer` | `string` | 格式化的计时文本 |
|
|
1959
|
+
| `timerRunning` | `boolean` | 计时器是否运行 |
|
|
1960
|
+
| `timerElapsed` | `number` | 已计时时长 |
|
|
1961
|
+
| `isOvertime` | `number \| boolean \| undefined` | 是否超时 |
|
|
1962
|
+
| `overdueDays` | `number` | 逾期天数 |
|
|
1963
|
+
| `overtimeText` | `string` | 超时文本 |
|
|
1964
|
+
| `overdueText` | `string` | 逾期文本 |
|
|
1965
|
+
| `daysText` | `string` | 天数文本 |
|
|
1966
|
+
| `progressClass` | `string` | 进度CSS类名 |
|
|
1874
1967
|
|
|
1875
1968
|
**TaskBar 特有参数(当 `type === 'task-bar'` 时):**
|
|
1876
1969
|
|
|
1877
|
-
| 参数名
|
|
1878
|
-
|
|
1879
|
-
| `status`
|
|
1880
|
-
| `statusType`
|
|
1881
|
-
| `isParent`
|
|
1882
|
-
| `progress`
|
|
1883
|
-
| `currentTimeScale` | `TimelineScale` | 当前时间刻度
|
|
1884
|
-
| `rowHeight`
|
|
1885
|
-
| `dayWidth`
|
|
1970
|
+
| 参数名 | 类型 | 说明 |
|
|
1971
|
+
| ------------------ | --------------- | ---------------------------------------------------------------------------------- |
|
|
1972
|
+
| `status` | `object` | 任务状态对象,包含 `type`, `color`, `bgColor`, `borderColor` |
|
|
1973
|
+
| `statusType` | `string` | 状态类型:`'completed'`, `'delayed'`, `'in-progress'`, `'not-started'`, `'parent'` |
|
|
1974
|
+
| `isParent` | `boolean` | 是否为父任务 |
|
|
1975
|
+
| `progress` | `number` | 任务进度(0-100) |
|
|
1976
|
+
| `currentTimeScale` | `TimelineScale` | 当前时间刻度 |
|
|
1977
|
+
| `rowHeight` | `number` | 行高(像素) |
|
|
1978
|
+
| `dayWidth` | `number` | 每天宽度(像素) |
|
|
1886
1979
|
|
|
1887
1980
|
**使用示例:**
|
|
1888
1981
|
|
|
@@ -1891,11 +1984,7 @@ const customMessages = {
|
|
|
1891
1984
|
<GanttChart :tasks="tasks">
|
|
1892
1985
|
<template #custom-task-content="slotProps">
|
|
1893
1986
|
<!-- 根据类型渲染不同内容 -->
|
|
1894
|
-
<CustomTaskContent
|
|
1895
|
-
:task="slotProps.task"
|
|
1896
|
-
:type="slotProps.type"
|
|
1897
|
-
:status="slotProps.status"
|
|
1898
|
-
/>
|
|
1987
|
+
<CustomTaskContent :task="slotProps.task" :type="slotProps.type" :status="slotProps.status" />
|
|
1899
1988
|
</template>
|
|
1900
1989
|
</GanttChart>
|
|
1901
1990
|
</template>
|
|
@@ -1913,8 +2002,8 @@ const tasks = ref<Task[]>([
|
|
|
1913
2002
|
name: '<strong>重要任务</strong>',
|
|
1914
2003
|
startDate: '2025-01-01',
|
|
1915
2004
|
endDate: '2025-01-10',
|
|
1916
|
-
progress: 50
|
|
1917
|
-
}
|
|
2005
|
+
progress: 50,
|
|
2006
|
+
},
|
|
1918
2007
|
])
|
|
1919
2008
|
</script>
|
|
1920
2009
|
```
|
|
@@ -1946,7 +2035,7 @@ const props = defineProps<Props>()
|
|
|
1946
2035
|
<div v-if="type === 'task-row'" class="task-row-content">
|
|
1947
2036
|
<span v-html="task.name" />
|
|
1948
2037
|
</div>
|
|
1949
|
-
|
|
2038
|
+
|
|
1950
2039
|
<!-- TaskBar 中的渲染 -->
|
|
1951
2040
|
<div v-else-if="type === 'task-bar'" class="task-bar-content">
|
|
1952
2041
|
<div class="task-icon" :style="{ color: status?.color }">📌</div>
|
|
@@ -1991,6 +2080,7 @@ const props = defineProps<Props>()
|
|
|
1991
2080
|
```
|
|
1992
2081
|
|
|
1993
2082
|
> **💡 使用场景**:
|
|
2083
|
+
>
|
|
1994
2084
|
> - 支持 HTML 格式的任务名称
|
|
1995
2085
|
> - 添加自定义图标、标签或徽章
|
|
1996
2086
|
> - 根据任务状态显示不同样式
|
|
@@ -1998,6 +2088,7 @@ const props = defineProps<Props>()
|
|
|
1998
2088
|
> - 显示额外的业务信息
|
|
1999
2089
|
|
|
2000
2090
|
> **⚠️ 注意事项**:
|
|
2091
|
+
>
|
|
2001
2092
|
> - 插槽内容会同时在 TaskRow 和 TaskBar 中渲染
|
|
2002
2093
|
> - 需要根据 `type` 参数区分渲染位置
|
|
2003
2094
|
> - TaskRow 和 TaskBar 的可用空间不同,需要适配布局
|