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