v 1.4.2 - 徽章更新
This commit is contained in:
+120
-123
@@ -2,7 +2,10 @@
|
|||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://www.npmjs.com/package/jordium-gantt-vue3">
|
<a href="https://www.npmjs.com/package/jordium-gantt-vue3">
|
||||||
<img src="https://img.shields.io/npm/v/jordium-gantt-vue3.svg" alt="npm version">
|
<img src="https://img.shields.io/npm/v/jordium-gantt-vue3?style=flat-square" alt="npm version">
|
||||||
|
</a>
|
||||||
|
<a href="https://www.npmjs.com/package/jordium-gantt-vue3">
|
||||||
|
<img src="https://img.shields.io/npm/dt/jordium-gantt-vue3?style=flat-square" alt="npm total">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://opensource.org/licenses/MIT">
|
<a href="https://opensource.org/licenses/MIT">
|
||||||
<img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License">
|
<img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License">
|
||||||
@@ -105,10 +108,7 @@ Create your first Gantt chart:
|
|||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<div style="height: 600px;">
|
<div style="height: 600px;">
|
||||||
<GanttChart
|
<GanttChart :tasks="tasks" :milestones="milestones" />
|
||||||
:tasks="tasks"
|
|
||||||
:milestones="milestones"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -123,7 +123,7 @@ const tasks = ref([
|
|||||||
name: 'Project Kickoff',
|
name: 'Project Kickoff',
|
||||||
startDate: '2025-01-01',
|
startDate: '2025-01-01',
|
||||||
endDate: '2025-01-10',
|
endDate: '2025-01-10',
|
||||||
progress: 100
|
progress: 100,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
@@ -131,7 +131,7 @@ const tasks = ref([
|
|||||||
startDate: '2025-01-11',
|
startDate: '2025-01-11',
|
||||||
endDate: '2025-01-20',
|
endDate: '2025-01-20',
|
||||||
progress: 80,
|
progress: 80,
|
||||||
predecessor: [1]
|
predecessor: [1],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 3,
|
id: 3,
|
||||||
@@ -139,8 +139,8 @@ const tasks = ref([
|
|||||||
startDate: '2025-01-21',
|
startDate: '2025-01-21',
|
||||||
endDate: '2025-02-05',
|
endDate: '2025-02-05',
|
||||||
progress: 50,
|
progress: 50,
|
||||||
predecessor: [2]
|
predecessor: [2],
|
||||||
}
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
const milestones = ref([
|
const milestones = ref([
|
||||||
@@ -148,8 +148,8 @@ const milestones = ref([
|
|||||||
id: 101,
|
id: 101,
|
||||||
name: 'Project Approval',
|
name: 'Project Approval',
|
||||||
date: '2025-01-01',
|
date: '2025-01-01',
|
||||||
type: 'milestone'
|
type: 'milestone',
|
||||||
}
|
},
|
||||||
])
|
])
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
@@ -158,6 +158,7 @@ const milestones = ref([
|
|||||||
<span><strong>Recommended: <a href="https://dovee.cc/a.php?anaxjgyz1ozZq2B">DOVE</a> VPN for fast and stable access.</strong></span> <span style="color:red;">(Note: Please use VPN services legally)</span>
|
<span><strong>Recommended: <a href="https://dovee.cc/a.php?anaxjgyz1ozZq2B">DOVE</a> VPN for fast and stable access.</strong></span> <span style="color:red;">(Note: Please use VPN services legally)</span>
|
||||||
|
|
||||||
## 🌞 NPM Package Usage Example
|
## 🌞 NPM Package Usage Example
|
||||||
|
|
||||||
Please refer to the npm-demo folder in the project.
|
Please refer to the npm-demo folder in the project.
|
||||||
It is a standalone project that can be opened and run independently using your IDE.
|
It is a standalone project that can be opened and run independently using your IDE.
|
||||||
Before running, make sure to install the Element Plus library and the jordium-gantt-vue3 plugin package.
|
Before running, make sure to install the Element Plus library and the jordium-gantt-vue3 plugin package.
|
||||||
@@ -168,6 +169,7 @@ npm install element-plus
|
|||||||
npm install jordium-gantt-vue3
|
npm install jordium-gantt-vue3
|
||||||
npm run dev
|
npm run dev
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📖 Component Guide
|
## 📖 Component Guide
|
||||||
@@ -179,7 +181,7 @@ npm run dev
|
|||||||
#### Basic Props
|
#### Basic Props
|
||||||
|
|
||||||
| Prop | Type | Default | Description |
|
| Prop | Type | Default | Description |
|
||||||
|------|------|---------|-------------|
|
| --------------------------- | --------- | ------- | ------------------------------------------------------------------------- |
|
||||||
| `tasks` | `Task[]` | `[]` | Array of task data |
|
| `tasks` | `Task[]` | `[]` | Array of task data |
|
||||||
| `milestones` | `Task[]` | `[]` | Array of milestone data (Note: Type is Task[], must set type='milestone') |
|
| `milestones` | `Task[]` | `[]` | Array of milestone data (Note: Type is Task[], must set type='milestone') |
|
||||||
| `showToolbar` | `boolean` | `true` | Whether to show the toolbar |
|
| `showToolbar` | `boolean` | `true` | Whether to show the toolbar |
|
||||||
@@ -193,7 +195,7 @@ npm run dev
|
|||||||
For complete configuration object documentation, see [⚙️ Configuration & Customization](#⚙️-configuration--customization) section.
|
For complete configuration object documentation, see [⚙️ Configuration & Customization](#⚙️-configuration--customization) section.
|
||||||
|
|
||||||
| Prop | Type | Default | Description |
|
| Prop | Type | Default | Description |
|
||||||
|------|------|---------|-------------|
|
| ---------------- | ---------------------------- | ----------------------------------------------------------------------- | ---------------------------- |
|
||||||
| `toolbarConfig` | `ToolbarConfig` | `{}` | Toolbar configuration |
|
| `toolbarConfig` | `ToolbarConfig` | `{}` | Toolbar configuration |
|
||||||
| `taskListConfig` | `TaskListConfig` | `undefined` | Task list configuration |
|
| `taskListConfig` | `TaskListConfig` | `undefined` | Task list configuration |
|
||||||
| `taskBarConfig` | `TaskBarConfig` | `undefined` | Task bar style configuration |
|
| `taskBarConfig` | `TaskBarConfig` | `undefined` | Task bar style configuration |
|
||||||
@@ -203,7 +205,7 @@ For complete configuration object documentation, see [⚙️ Configuration & Cus
|
|||||||
#### Callback Props
|
#### Callback Props
|
||||||
|
|
||||||
| Prop | Type | Description |
|
| Prop | Type | Description |
|
||||||
|------|------|-------------|
|
| -------------------- | ------------------------------------ | ------------------------------------------------------------------------------------ |
|
||||||
| `onTodayLocate` | `() => void` | Toolbar "Today" button click callback |
|
| `onTodayLocate` | `() => void` | Toolbar "Today" button click callback |
|
||||||
| `onExportCsv` | `() => boolean \| void` | Toolbar "Export CSV" button click callback, return `false` to prevent default export |
|
| `onExportCsv` | `() => boolean \| void` | Toolbar "Export CSV" button click callback, return `false` to prevent default export |
|
||||||
| `onExportPdf` | `() => void` | Toolbar "Export PDF" button click callback |
|
| `onExportPdf` | `() => void` | Toolbar "Export PDF" button click callback |
|
||||||
@@ -216,13 +218,14 @@ For complete configuration object documentation, see [⚙️ Configuration & Cus
|
|||||||
#### Component Events
|
#### Component Events
|
||||||
|
|
||||||
For complete event documentation, see:
|
For complete event documentation, see:
|
||||||
|
|
||||||
- **Task-related events**: See [Task Management](#task-management) section below
|
- **Task-related events**: See [Task Management](#task-management) section below
|
||||||
- **Milestone-related events**: See [Milestone Management](#milestone-management) section below
|
- **Milestone-related events**: See [Milestone Management](#milestone-management) section below
|
||||||
|
|
||||||
**Event List Overview:**
|
**Event List Overview:**
|
||||||
|
|
||||||
| Event Name | Parameters | Description |
|
| Event Name | Parameters | Description |
|
||||||
|------------|------------|-------------|
|
| ------------------------ | --------------------------------- | -------------------------------------- |
|
||||||
| `add-task` | - | Clicked toolbar "Add Task" button |
|
| `add-task` | - | Clicked toolbar "Add Task" button |
|
||||||
| `task-click` | `(task: Task, event: MouseEvent)` | Clicked task |
|
| `task-click` | `(task: Task, event: MouseEvent)` | Clicked task |
|
||||||
| `task-double-click` | `(task: Task)` | Double-clicked task |
|
| `task-double-click` | `(task: Task)` | Double-clicked task |
|
||||||
@@ -261,8 +264,8 @@ const tasks = ref([
|
|||||||
name: 'Task 1',
|
name: 'Task 1',
|
||||||
startDate: '2025-01-01',
|
startDate: '2025-01-01',
|
||||||
endDate: '2025-01-10',
|
endDate: '2025-01-10',
|
||||||
progress: 100
|
progress: 100,
|
||||||
}
|
},
|
||||||
])
|
])
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
@@ -272,10 +275,7 @@ const tasks = ref([
|
|||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<div style="height: 600px;">
|
<div style="height: 600px;">
|
||||||
<GanttChart
|
<GanttChart :tasks="tasks" :milestones="milestones" />
|
||||||
:tasks="tasks"
|
|
||||||
:milestones="milestones"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -290,8 +290,8 @@ const tasks = ref([
|
|||||||
name: 'Project Kickoff',
|
name: 'Project Kickoff',
|
||||||
startDate: '2025-01-01',
|
startDate: '2025-01-01',
|
||||||
endDate: '2025-01-10',
|
endDate: '2025-01-10',
|
||||||
progress: 100
|
progress: 100,
|
||||||
}
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
const milestones = ref([
|
const milestones = ref([
|
||||||
@@ -300,8 +300,8 @@ const milestones = ref([
|
|||||||
name: 'Project Approval',
|
name: 'Project Approval',
|
||||||
startDate: '2025-01-01',
|
startDate: '2025-01-01',
|
||||||
type: 'milestone',
|
type: 'milestone',
|
||||||
icon: 'diamond'
|
icon: 'diamond',
|
||||||
}
|
},
|
||||||
])
|
])
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
@@ -344,7 +344,7 @@ const addTask = () => {
|
|||||||
name: 'New Task',
|
name: 'New Task',
|
||||||
startDate: new Date().toISOString().split('T')[0],
|
startDate: new Date().toISOString().split('T')[0],
|
||||||
endDate: new Date().toISOString().split('T')[0],
|
endDate: new Date().toISOString().split('T')[0],
|
||||||
progress: 0
|
progress: 0,
|
||||||
}
|
}
|
||||||
tasks.value.push(newTask)
|
tasks.value.push(newTask)
|
||||||
}
|
}
|
||||||
@@ -354,16 +354,16 @@ const addMilestone = () => {
|
|||||||
id: Date.now(),
|
id: Date.now(),
|
||||||
name: 'New Milestone',
|
name: 'New Milestone',
|
||||||
startDate: new Date().toISOString().split('T')[0],
|
startDate: new Date().toISOString().split('T')[0],
|
||||||
type: 'milestone'
|
type: 'milestone',
|
||||||
}
|
}
|
||||||
milestones.value.push(newMilestone)
|
milestones.value.push(newMilestone)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleTaskAdded = (e) => {
|
const handleTaskAdded = e => {
|
||||||
console.log('Task added:', e.task)
|
console.log('Task added:', e.task)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleMilestoneSaved = (milestone) => {
|
const handleMilestoneSaved = milestone => {
|
||||||
console.log('Milestone saved:', milestone)
|
console.log('Milestone saved:', milestone)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -378,7 +378,7 @@ Tasks are the core elements of the Gantt chart. The component provides complete
|
|||||||
#### Task Data Structure
|
#### Task Data Structure
|
||||||
|
|
||||||
| Field | Type | Required | Default | Description |
|
| Field | Type | Required | Default | Description |
|
||||||
|-------|------|----------|---------|-------------|
|
| ------------------ | ---------- | -------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `id` | `number` | ✅ | - | Unique task identifier |
|
| `id` | `number` | ✅ | - | Unique task identifier |
|
||||||
| `name` | `string` | ✅ | - | Task name |
|
| `name` | `string` | ✅ | - | Task name |
|
||||||
| `startDate` | `string` | - | - | Start date, format: 'YYYY-MM-DD' or 'YYYY-MM-DD HH:mm' |
|
| `startDate` | `string` | - | - | Start date, format: 'YYYY-MM-DD' or 'YYYY-MM-DD HH:mm' |
|
||||||
@@ -408,6 +408,7 @@ Tasks are the core elements of the Gantt chart. The component provides complete
|
|||||||
> **Custom Property Extensions**: The Task interface supports adding arbitrary custom fields, such as: `priority`, `tags`, `status`, `department`, and other business-related fields.
|
> **Custom Property Extensions**: The Task interface supports adding arbitrary custom fields, such as: `priority`, `tags`, `status`, `department`, and other business-related fields.
|
||||||
>
|
>
|
||||||
> **Predecessor Field Notes**:
|
> **Predecessor Field Notes**:
|
||||||
|
>
|
||||||
> - **Standard format** (recommended): `predecessor: [1, 2, 3]` - number array
|
> - **Standard format** (recommended): `predecessor: [1, 2, 3]` - number array
|
||||||
> **Compatible format 1**: `predecessor: '1,2,3'` - comma-separated string
|
> **Compatible format 1**: `predecessor: '1,2,3'` - comma-separated string
|
||||||
> - **Compatible format 2**: `predecessor: ['1', '2', '3']` - string array
|
> - **Compatible format 2**: `predecessor: ['1', '2', '3']` - string array
|
||||||
@@ -417,7 +418,7 @@ Tasks are the core elements of the Gantt chart. The component provides complete
|
|||||||
#### Task-Related Props
|
#### Task-Related Props
|
||||||
|
|
||||||
| Prop | Type | Default | Description |
|
| Prop | Type | Default | Description |
|
||||||
|------|------|---------|-------------|
|
| --------------------- | ---------------- | ----------- | --------------------------------------------------------------------------------------------- |
|
||||||
| `tasks` | `Task[]` | `[]` | Array of task data |
|
| `tasks` | `Task[]` | `[]` | Array of task data |
|
||||||
| `useDefaultDrawer` | `boolean` | `true` | Whether to use built-in task edit drawer (TaskDrawer) |
|
| `useDefaultDrawer` | `boolean` | `true` | Whether to use built-in task edit drawer (TaskDrawer) |
|
||||||
| `taskBarConfig` | `TaskBarConfig` | `{}` | Task bar style configuration, see [TaskBarConfig Configuration](#taskbarconfig-configuration) |
|
| `taskBarConfig` | `TaskBarConfig` | `{}` | Task bar style configuration, see [TaskBarConfig Configuration](#taskbarconfig-configuration) |
|
||||||
@@ -425,6 +426,7 @@ Tasks are the core elements of the Gantt chart. The component provides complete
|
|||||||
| `autoSortByStartDate` | `boolean` | `false` | Whether to automatically sort tasks by start date |
|
| `autoSortByStartDate` | `boolean` | `false` | Whether to automatically sort tasks by start date |
|
||||||
|
|
||||||
**Configuration Notes**:
|
**Configuration Notes**:
|
||||||
|
|
||||||
- **Default mode**: `useDefaultDrawer=true` (default), double-click task to auto-open built-in TaskDrawer
|
- **Default mode**: `useDefaultDrawer=true` (default), double-click task to auto-open built-in TaskDrawer
|
||||||
- **Custom editor**: `useDefaultDrawer=false` disables built-in drawer, listen to `@task-double-click` event to open custom editor
|
- **Custom editor**: `useDefaultDrawer=false` disables built-in drawer, listen to `@task-double-click` event to open custom editor
|
||||||
- **Read-only mode**: `useDefaultDrawer=false` and don't listen to `@task-double-click` event, user double-click task has no response
|
- **Read-only mode**: `useDefaultDrawer=false` and don't listen to `@task-double-click` event, user double-click task has no response
|
||||||
@@ -434,7 +436,7 @@ Tasks are the core elements of the Gantt chart. The component provides complete
|
|||||||
> **💡 Event-Driven Architecture**: Component adopts pure event-driven design. All user operations (add, edit, delete, drag, etc.) will trigger corresponding events for easy external listening and handling.
|
> **💡 Event-Driven Architecture**: Component adopts pure event-driven design. All user operations (add, edit, delete, drag, etc.) will trigger corresponding events for easy external listening and handling.
|
||||||
|
|
||||||
| Event Name | Parameters | When Triggered | Description |
|
| Event Name | Parameters | When Triggered | Description |
|
||||||
|------------|------------|----------------|-------------|
|
| -------------------- | ----------------------------------------- | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `add-task` | - | When clicking toolbar "Add Task" button | Can be used for custom add task logic. If `useDefaultDrawer=true`, component will auto-open built-in TaskDrawer |
|
| `add-task` | - | When clicking toolbar "Add Task" button | Can be used for custom add task logic. If `useDefaultDrawer=true`, component will auto-open built-in TaskDrawer |
|
||||||
| `task-click` | `(task: Task, event: MouseEvent) => void` | When clicking task bar | Triggered on single-click task |
|
| `task-click` | `(task: Task, event: MouseEvent) => void` | When clicking task bar | Triggered on single-click task |
|
||||||
| `task-double-click` | `(task: Task) => void` | When double-clicking task bar | Double-click task **always triggers**. When `useDefaultDrawer=true`, component will additionally open built-in editor; when `false`, won't open. Event triggering is independent of property value |
|
| `task-double-click` | `(task: Task) => void` | When double-clicking task bar | Double-click task **always triggers**. When `useDefaultDrawer=true`, component will additionally open built-in editor; when `false`, won't open. Event triggering is independent of property value |
|
||||||
@@ -449,6 +451,7 @@ Tasks are the core elements of the Gantt chart. The component provides complete
|
|||||||
| `timer-stopped` | `(task: Task) => void` | When task timer stops | Stop recording task hours |
|
| `timer-stopped` | `(task: Task) => void` | When task timer stops | Stop recording task hours |
|
||||||
|
|
||||||
**Data Synchronization Notes**:
|
**Data Synchronization Notes**:
|
||||||
|
|
||||||
- ✅ **Component auto-updates internally**: For all task CRUD operations, component will auto-update `props.tasks` data
|
- ✅ **Component auto-updates internally**: For all task CRUD operations, component will auto-update `props.tasks` data
|
||||||
- ✅ **Events are for notification only**: External event listeners are mainly for: showing messages, calling backend APIs, updating other related data, etc.
|
- ✅ **Events are for notification only**: External event listeners are mainly for: showing messages, calling backend APIs, updating other related data, etc.
|
||||||
- ❌ **Avoid duplicate operations**: Don't modify `tasks` data again in event handlers, otherwise it will cause duplicate updates
|
- ❌ **Avoid duplicate operations**: Don't modify `tasks` data again in event handlers, otherwise it will cause duplicate updates
|
||||||
@@ -494,7 +497,7 @@ const tasks = ref<Task[]>([
|
|||||||
progress: 60,
|
progress: 60,
|
||||||
assignee: 'Bob',
|
assignee: 'Bob',
|
||||||
predecessor: [1], // Depends on task 1
|
predecessor: [1], // Depends on task 1
|
||||||
}
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
// Toolbar "Add Task" button click event
|
// Toolbar "Add Task" button click event
|
||||||
@@ -567,7 +570,7 @@ const tasks = ref<Task[]>([
|
|||||||
startDate: '2025-01-01',
|
startDate: '2025-01-01',
|
||||||
endDate: '2025-01-10',
|
endDate: '2025-01-10',
|
||||||
progress: 100,
|
progress: 100,
|
||||||
predecessor: [] // No predecessors
|
predecessor: [], // No predecessors
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
@@ -575,7 +578,7 @@ const tasks = ref<Task[]>([
|
|||||||
startDate: '2025-01-11',
|
startDate: '2025-01-11',
|
||||||
endDate: '2025-01-20',
|
endDate: '2025-01-20',
|
||||||
progress: 80,
|
progress: 80,
|
||||||
predecessor: [1] // Depends on task 1 (Requirements Analysis)
|
predecessor: [1], // Depends on task 1 (Requirements Analysis)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 3,
|
id: 3,
|
||||||
@@ -583,7 +586,7 @@ const tasks = ref<Task[]>([
|
|||||||
startDate: '2025-01-11',
|
startDate: '2025-01-11',
|
||||||
endDate: '2025-01-18',
|
endDate: '2025-01-18',
|
||||||
progress: 90,
|
progress: 90,
|
||||||
predecessor: [1] // Depends on task 1
|
predecessor: [1], // Depends on task 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 4,
|
id: 4,
|
||||||
@@ -591,7 +594,7 @@ const tasks = ref<Task[]>([
|
|||||||
startDate: '2025-01-21',
|
startDate: '2025-01-21',
|
||||||
endDate: '2025-02-10',
|
endDate: '2025-02-10',
|
||||||
progress: 60,
|
progress: 60,
|
||||||
predecessor: [2] // Depends on task 2 (System Design)
|
predecessor: [2], // Depends on task 2 (System Design)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 5,
|
id: 5,
|
||||||
@@ -599,7 +602,7 @@ const tasks = ref<Task[]>([
|
|||||||
startDate: '2025-01-19',
|
startDate: '2025-01-19',
|
||||||
endDate: '2025-02-08',
|
endDate: '2025-02-08',
|
||||||
progress: 70,
|
progress: 70,
|
||||||
predecessor: [2, 3] // Depends on both task 2 and 3
|
predecessor: [2, 3], // Depends on both task 2 and 3
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 6,
|
id: 6,
|
||||||
@@ -607,8 +610,8 @@ const tasks = ref<Task[]>([
|
|||||||
startDate: '2025-02-11',
|
startDate: '2025-02-11',
|
||||||
endDate: '2025-02-20',
|
endDate: '2025-02-20',
|
||||||
progress: 30,
|
progress: 30,
|
||||||
predecessor: [4, 5] // Depends on frontend and backend development completion
|
predecessor: [4, 5], // Depends on frontend and backend development completion
|
||||||
}
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
// Triggered when adding predecessor via context menu
|
// Triggered when adding predecessor via context menu
|
||||||
@@ -630,6 +633,7 @@ const handleSuccessorAdded = (event: { targetTask: Task; newTask: Task }) => {
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Dependency Relationship Notes**:
|
**Dependency Relationship Notes**:
|
||||||
|
|
||||||
- **`predecessor` field supports multiple formats**:
|
- **`predecessor` field supports multiple formats**:
|
||||||
- Standard format (recommended): `[1, 2, 3]` - number array
|
- Standard format (recommended): `[1, 2, 3]` - number array
|
||||||
- Compatible format 1: `'1,2,3'` - comma-separated string
|
- Compatible format 1: `'1,2,3'` - comma-separated string
|
||||||
@@ -698,7 +702,7 @@ const handleAddMilestone = () => {
|
|||||||
console.log('Preparing to add milestone (triggered by custom button)')
|
console.log('Preparing to add milestone (triggered by custom button)')
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleTaskAdded = (e) => {
|
const handleTaskAdded = e => {
|
||||||
console.log('Task added:', e.task)
|
console.log('Task added:', e.task)
|
||||||
// Call API to save...
|
// Call API to save...
|
||||||
}
|
}
|
||||||
@@ -706,6 +710,7 @@ const handleTaskAdded = (e) => {
|
|||||||
```
|
```
|
||||||
|
|
||||||
> **💡 Flexibility Design**:
|
> **💡 Flexibility Design**:
|
||||||
|
>
|
||||||
> - Show toolbar + default editor: Simplest out-of-the-box approach
|
> - Show toolbar + default editor: Simplest out-of-the-box approach
|
||||||
> - Hide toolbar + custom buttons + default editor: Custom control bar style while keeping default edit functionality
|
> - Hide toolbar + custom buttons + default editor: Custom control bar style while keeping default edit functionality
|
||||||
> - Hide toolbar + custom buttons + custom editor: Fully customize all interaction logic
|
> - Hide toolbar + custom buttons + custom editor: Fully customize all interaction logic
|
||||||
@@ -721,7 +726,7 @@ Milestones are used to mark important time points in a project, such as project
|
|||||||
#### Milestone Data Structure
|
#### Milestone Data Structure
|
||||||
|
|
||||||
| Field | Type | Required | Default | Description |
|
| Field | Type | Required | Default | Description |
|
||||||
|-------|------|----------|---------|-------------|
|
| ------------- | -------- | -------- | ------------- | --------------------------------------------------------------------------- |
|
||||||
| `id` | `number` | ✅ | - | Unique milestone identifier |
|
| `id` | `number` | ✅ | - | Unique milestone identifier |
|
||||||
| `name` | `string` | ✅ | - | Milestone name |
|
| `name` | `string` | ✅ | - | Milestone name |
|
||||||
| `startDate` | `string` | ✅ | - | Milestone date, format: 'YYYY-MM-DD' or 'YYYY-MM-DD HH:mm' |
|
| `startDate` | `string` | ✅ | - | Milestone date, format: 'YYYY-MM-DD' or 'YYYY-MM-DD HH:mm' |
|
||||||
@@ -736,16 +741,18 @@ Milestones are used to mark important time points in a project, such as project
|
|||||||
#### Milestone-Related Props
|
#### Milestone-Related Props
|
||||||
|
|
||||||
| Prop | Type | Default | Description |
|
| Prop | Type | Default | Description |
|
||||||
|------|------|---------|-------------|
|
| --------------------------- | --------- | ------- | ----------------------------------------------------------------- |
|
||||||
| `milestones` | `Task[]` | `[]` | Array of milestone data (type is Task[], ensure type='milestone') |
|
| `milestones` | `Task[]` | `[]` | Array of milestone data (type is Task[], ensure type='milestone') |
|
||||||
| `useDefaultMilestoneDialog` | `boolean` | `true` | Whether to use built-in milestone edit dialog (MilestoneDialog) |
|
| `useDefaultMilestoneDialog` | `boolean` | `true` | Whether to use built-in milestone edit dialog (MilestoneDialog) |
|
||||||
|
|
||||||
**Configuration Notes**:
|
**Configuration Notes**:
|
||||||
|
|
||||||
- **Default mode**: `useDefaultMilestoneDialog=true` (default), double-click milestone to auto-open built-in MilestoneDialog
|
- **Default mode**: `useDefaultMilestoneDialog=true` (default), double-click milestone to auto-open built-in MilestoneDialog
|
||||||
- **Disable editor**: `useDefaultMilestoneDialog=false`, double-click milestone has no response (component doesn't open any editor)
|
- **Disable editor**: `useDefaultMilestoneDialog=false`, double-click milestone has no response (component doesn't open any editor)
|
||||||
- **Custom editor**: Can listen to `onMilestoneDoubleClick` callback or related events to implement custom editing logic
|
- **Custom editor**: Can listen to `onMilestoneDoubleClick` callback or related events to implement custom editing logic
|
||||||
|
|
||||||
> **💡 Differences Between Milestones and Tasks**:
|
> **💡 Differences Between Milestones and Tasks**:
|
||||||
|
>
|
||||||
> - Milestone data is managed independently via `milestones` prop, separate from `tasks`
|
> - Milestone data is managed independently via `milestones` prop, separate from `tasks`
|
||||||
> - Milestone object's `type` field must be set to `'milestone'`
|
> - Milestone object's `type` field must be set to `'milestone'`
|
||||||
> - Milestones don't support child tasks, dependency relationships, and other complex structures
|
> - Milestones don't support child tasks, dependency relationships, and other complex structures
|
||||||
@@ -755,13 +762,12 @@ Milestones are used to mark important time points in a project, such as project
|
|||||||
|
|
||||||
> **⚠️ Deprecated**: Please use the new event-driven API (see "Milestone Events" section below)
|
> **⚠️ Deprecated**: Please use the new event-driven API (see "Milestone Events" section below)
|
||||||
|
|
||||||
|
|
||||||
#### Milestone Events
|
#### Milestone Events
|
||||||
|
|
||||||
> **💡 Event-Driven Architecture**: Milestone management adopts event-driven design. Using event API is recommended over callback functions.
|
> **💡 Event-Driven Architecture**: Milestone management adopts event-driven design. Using event API is recommended over callback functions.
|
||||||
|
|
||||||
| Event Name | Parameters | When Triggered | Description |
|
| Event Name | Parameters | When Triggered | Description |
|
||||||
|------------|------------|----------------|-------------|
|
| ------------------------ | --------------------------------------- | -------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `add-milestone` | - | When clicking toolbar "Add Milestone" button | Can be used for custom add milestone logic. If `useDefaultMilestoneDialog=true`, component will auto-open built-in MilestoneDialog |
|
| `add-milestone` | - | When clicking toolbar "Add Milestone" button | Can be used for custom add milestone logic. If `useDefaultMilestoneDialog=true`, component will auto-open built-in MilestoneDialog |
|
||||||
| `milestone-saved` | `(milestone: Task) => void` | After milestone saved (add or edit) | Triggered after saving milestone via built-in MilestoneDialog. **Note**: Component has auto-updated `milestones` data, external only needs to listen to this event for additional processing (like calling API to save) |
|
| `milestone-saved` | `(milestone: Task) => void` | After milestone saved (add or edit) | Triggered after saving milestone via built-in MilestoneDialog. **Note**: Component has auto-updated `milestones` data, external only needs to listen to this event for additional processing (like calling API to save) |
|
||||||
| `milestone-deleted` | `{ milestoneId: number }` | After milestone deleted | Triggered after deleting milestone via built-in MilestoneDialog. **Note**: Component has auto-updated `milestones` data, external only needs to listen to this event for additional processing |
|
| `milestone-deleted` | `{ milestoneId: number }` | After milestone deleted | Triggered after deleting milestone via built-in MilestoneDialog. **Note**: Component has auto-updated `milestones` data, external only needs to listen to this event for additional processing |
|
||||||
@@ -769,6 +775,7 @@ Milestones are used to mark important time points in a project, such as project
|
|||||||
| `milestone-drag-end` | `(milestone: Task) => void` | When milestone drag ends | Milestone date updated. **Note**: Component has auto-updated `milestones` data |
|
| `milestone-drag-end` | `(milestone: Task) => void` | When milestone drag ends | Milestone date updated. **Note**: Component has auto-updated `milestones` data |
|
||||||
|
|
||||||
**Data Synchronization Notes**:
|
**Data Synchronization Notes**:
|
||||||
|
|
||||||
- ✅ **Component auto-updates internally**: For all milestone CRUD operations, component will auto-update `props.milestones` data
|
- ✅ **Component auto-updates internally**: For all milestone CRUD operations, component will auto-update `props.milestones` data
|
||||||
- ✅ **Events are for notification only**: External event listeners are mainly for: showing messages, calling backend APIs, updating other related data, etc.
|
- ✅ **Events are for notification only**: External event listeners are mainly for: showing messages, calling backend APIs, updating other related data, etc.
|
||||||
- ❌ **Avoid duplicate operations**: Don't modify `milestones` data again in event handlers, otherwise it will cause duplicate updates
|
- ❌ **Avoid duplicate operations**: Don't modify `milestones` data again in event handlers, otherwise it will cause duplicate updates
|
||||||
@@ -805,15 +812,15 @@ const milestones = ref<Task[]>([
|
|||||||
type: 'milestone',
|
type: 'milestone',
|
||||||
icon: 'diamond',
|
icon: 'diamond',
|
||||||
assignee: 'Project Manager',
|
assignee: 'Project Manager',
|
||||||
description: 'Official project kickoff'
|
description: 'Official project kickoff',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 102,
|
id: 102,
|
||||||
name: 'Requirements Review',
|
name: 'Requirements Review',
|
||||||
startDate: '2025-01-15',
|
startDate: '2025-01-15',
|
||||||
type: 'milestone',
|
type: 'milestone',
|
||||||
icon: 'flag'
|
icon: 'flag',
|
||||||
}
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
// Toolbar "Add Milestone" button click event
|
// Toolbar "Add Milestone" button click event
|
||||||
@@ -896,8 +903,8 @@ const milestones = ref<Task[]>([
|
|||||||
type: 'milestone',
|
type: 'milestone',
|
||||||
icon: 'diamond',
|
icon: 'diamond',
|
||||||
assignee: 'Project Manager',
|
assignee: 'Project Manager',
|
||||||
description: 'Official project kickoff'
|
description: 'Official project kickoff',
|
||||||
}
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
const customDialogVisible = ref(false)
|
const customDialogVisible = ref(false)
|
||||||
@@ -927,7 +934,7 @@ const handleCustomDialogSave = (milestone: Task) => {
|
|||||||
const newMilestone = {
|
const newMilestone = {
|
||||||
...milestone,
|
...milestone,
|
||||||
id: Date.now(), // Generate new ID
|
id: Date.now(), // Generate new ID
|
||||||
type: 'milestone'
|
type: 'milestone',
|
||||||
}
|
}
|
||||||
milestones.value.push(newMilestone)
|
milestones.value.push(newMilestone)
|
||||||
|
|
||||||
@@ -1028,9 +1035,7 @@ const handleMilestoneDrag = (milestone: Task) => {
|
|||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button v-if="!isNew" type="danger" @click="handleDelete">
|
<el-button v-if="!isNew" type="danger" @click="handleDelete"> Delete </el-button>
|
||||||
Delete
|
|
||||||
</el-button>
|
|
||||||
<el-button @click="handleClose">Cancel</el-button>
|
<el-button @click="handleClose">Cancel</el-button>
|
||||||
<el-button type="primary" @click="handleSave">Save</el-button>
|
<el-button type="primary" @click="handleSave">Save</el-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -1063,10 +1068,12 @@ const form = ref({
|
|||||||
assignee: '',
|
assignee: '',
|
||||||
icon: 'diamond',
|
icon: 'diamond',
|
||||||
description: '',
|
description: '',
|
||||||
type: 'milestone'
|
type: 'milestone',
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(() => props.visible, (val) => {
|
watch(
|
||||||
|
() => props.visible,
|
||||||
|
val => {
|
||||||
dialogVisible.value = val
|
dialogVisible.value = val
|
||||||
if (val) {
|
if (val) {
|
||||||
if (props.milestone) {
|
if (props.milestone) {
|
||||||
@@ -1081,13 +1088,14 @@ watch(() => props.visible, (val) => {
|
|||||||
assignee: '',
|
assignee: '',
|
||||||
icon: 'diamond',
|
icon: 'diamond',
|
||||||
description: '',
|
description: '',
|
||||||
type: 'milestone'
|
type: 'milestone',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
watch(dialogVisible, (val) => {
|
watch(dialogVisible, val => {
|
||||||
emit('update:visible', val)
|
emit('update:visible', val)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -1112,6 +1120,7 @@ const handleDelete = () => {
|
|||||||
```
|
```
|
||||||
|
|
||||||
> **💡 Custom Dialog Notes**:
|
> **💡 Custom Dialog Notes**:
|
||||||
|
>
|
||||||
> - Set `use-default-milestone-dialog="false"` to disable built-in dialog
|
> - Set `use-default-milestone-dialog="false"` to disable built-in dialog
|
||||||
> - Listen to `@add-milestone` event to open custom dialog
|
> - Listen to `@add-milestone` event to open custom dialog
|
||||||
> - Need to manually manage `milestones` array CRUD operations
|
> - Need to manually manage `milestones` array CRUD operations
|
||||||
@@ -1133,7 +1142,7 @@ Customize the toolbar functional buttons and time scale options.
|
|||||||
**Type Definition:**
|
**Type Definition:**
|
||||||
|
|
||||||
| Field | Type | Default | Description |
|
| Field | Type | Default | Description |
|
||||||
|-------|------|---------|-------------|
|
| --------------------- | ----------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
|
||||||
| `showAddTask` | `boolean` | `true` | Show "Add Task" button |
|
| `showAddTask` | `boolean` | `true` | Show "Add Task" button |
|
||||||
| `showAddMilestone` | `boolean` | `true` | Show "Add Milestone" button |
|
| `showAddMilestone` | `boolean` | `true` | Show "Add Milestone" button |
|
||||||
| `showTodayLocate` | `boolean` | `true` | Show "Locate to Today" button |
|
| `showTodayLocate` | `boolean` | `true` | Show "Locate to Today" button |
|
||||||
@@ -1167,10 +1176,7 @@ TimelineScale.YEAR // 'year' - Year view
|
|||||||
|
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<GanttChart
|
<GanttChart :tasks="tasks" :toolbar-config="toolbarConfig" />
|
||||||
:tasks="tasks"
|
|
||||||
:toolbar-config="toolbarConfig"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -1188,11 +1194,17 @@ const toolbarConfig: ToolbarConfig = {
|
|||||||
showTheme: true, // Show theme switch button
|
showTheme: true, // Show theme switch button
|
||||||
showFullscreen: true, // Show fullscreen button
|
showFullscreen: true, // Show fullscreen button
|
||||||
showTimeScale: true, // Show time scale button group
|
showTimeScale: true, // Show time scale button group
|
||||||
timeScaleDimensions: [ // Show all time scale dimensions
|
timeScaleDimensions: [
|
||||||
'hour', 'day', 'week', 'month', 'quarter', 'year'
|
// Show all time scale dimensions
|
||||||
|
'hour',
|
||||||
|
'day',
|
||||||
|
'week',
|
||||||
|
'month',
|
||||||
|
'quarter',
|
||||||
|
'year',
|
||||||
],
|
],
|
||||||
defaultTimeScale: 'week', // Default week view
|
defaultTimeScale: 'week', // Default week view
|
||||||
showExpandCollapse: true // Show expand/collapse button
|
showExpandCollapse: true, // Show expand/collapse button
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
@@ -1213,11 +1225,14 @@ const toolbarConfig: ToolbarConfig = {
|
|||||||
showTheme: true, // Keep theme switch
|
showTheme: true, // Keep theme switch
|
||||||
showFullscreen: true, // Keep fullscreen
|
showFullscreen: true, // Keep fullscreen
|
||||||
showTimeScale: true, // Show time scale
|
showTimeScale: true, // Show time scale
|
||||||
timeScaleDimensions: [ // Only show day/week/month scales
|
timeScaleDimensions: [
|
||||||
'day', 'week', 'month'
|
// Only show day/week/month scales
|
||||||
|
'day',
|
||||||
|
'week',
|
||||||
|
'month',
|
||||||
],
|
],
|
||||||
defaultTimeScale: 'week', // Default week view
|
defaultTimeScale: 'week', // Default week view
|
||||||
showExpandCollapse: true // Keep expand/collapse
|
showExpandCollapse: true, // Keep expand/collapse
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
@@ -1235,9 +1250,9 @@ const toolbarConfig: ToolbarConfig = {
|
|||||||
TimelineScale.DAY,
|
TimelineScale.DAY,
|
||||||
TimelineScale.WEEK,
|
TimelineScale.WEEK,
|
||||||
TimelineScale.MONTH,
|
TimelineScale.MONTH,
|
||||||
TimelineScale.QUARTER
|
TimelineScale.QUARTER,
|
||||||
],
|
],
|
||||||
defaultTimeScale: TimelineScale.MONTH // Default month view
|
defaultTimeScale: TimelineScale.MONTH, // Default month view
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
@@ -1260,12 +1275,13 @@ const toolbarConfig: ToolbarConfig = {
|
|||||||
showTimeScale: true, // Keep time scale switch
|
showTimeScale: true, // Keep time scale switch
|
||||||
timeScaleDimensions: ['week', 'month'],
|
timeScaleDimensions: ['week', 'month'],
|
||||||
defaultTimeScale: 'month',
|
defaultTimeScale: 'month',
|
||||||
showExpandCollapse: false // Hide expand/collapse
|
showExpandCollapse: false, // Hide expand/collapse
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
> **💡 Configuration Recommendations**:
|
> **💡 Configuration Recommendations**:
|
||||||
|
>
|
||||||
> - **Default configuration**:When not passed, all buttons are shown by default
|
> - **Default configuration**:When not passed, all buttons are shown by default
|
||||||
> - **Show as needed**: Hide unnecessary feature buttons based on business requirements
|
> - **Show as needed**: Hide unnecessary feature buttons based on business requirements
|
||||||
> - **Time scale**:`timeScaleDimensions` controls which time dimensions to display, recommend selecting 2-4 common dimensions
|
> - **Time scale**:`timeScaleDimensions` controls which time dimensions to display, recommend selecting 2-4 common dimensions
|
||||||
@@ -1278,7 +1294,7 @@ Customize task list display columns, width limits, etc. Task list is located on
|
|||||||
**Type Definition:**
|
**Type Definition:**
|
||||||
|
|
||||||
| Field | Type | Default | Description |
|
| Field | Type | Default | Description |
|
||||||
|--------|------|--------|------|
|
| ---------------- | ------------------------ | ----------------- | ---------------------------------------------------------------------------------------------------------------- |
|
||||||
| `columns` | `TaskListColumnConfig[]` | Default 8 columns | Task list column configuration array, defines which columns to display and their properties |
|
| `columns` | `TaskListColumnConfig[]` | Default 8 columns | Task list column configuration array, defines which columns to display and their properties |
|
||||||
| `showAllColumns` | `boolean` | `true` | Whether to show all columns. When `true`, ignores `visible` setting in `columns` |
|
| `showAllColumns` | `boolean` | `true` | Whether to show all columns. When `true`, ignores `visible` setting in `columns` |
|
||||||
| `defaultWidth` | `number \| string` | `320` | Default expanded width. Supports pixel number (like `320`) or percentage string (like `'30%'`) |
|
| `defaultWidth` | `number \| string` | `320` | Default expanded width. Supports pixel number (like `320`) or percentage string (like `'30%'`) |
|
||||||
@@ -1288,7 +1304,7 @@ Customize task list display columns, width limits, etc. Task list is located on
|
|||||||
**TaskListColumnConfig Type Definition:**
|
**TaskListColumnConfig Type Definition:**
|
||||||
|
|
||||||
| Field | Type | Required | Description |
|
| Field | Type | Required | Description |
|
||||||
|--------|------|------|------|
|
| ---------- | --------- | -------- | ----------------------------------------------------------------------------------------------- |
|
||||||
| `key` | `string` | ✅ | Unique column identifier, used to access fields in Task object and for internationalization |
|
| `key` | `string` | ✅ | Unique column identifier, used to access fields in Task object and for internationalization |
|
||||||
| `label` | `string` | - | Column display label (header text) |
|
| `label` | `string` | - | Column display label (header text) |
|
||||||
| `cssClass` | `string` | - | Custom CSS class name |
|
| `cssClass` | `string` | - | Custom CSS class name |
|
||||||
@@ -1299,10 +1315,7 @@ Customize task list display columns, width limits, etc. Task list is located on
|
|||||||
|
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<GanttChart
|
<GanttChart :tasks="tasks" :task-list-config="taskListConfig" />
|
||||||
:tasks="tasks"
|
|
||||||
:task-list-config="taskListConfig"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -1322,10 +1335,7 @@ const taskListConfig: TaskListConfig = {
|
|||||||
|
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<GanttChart
|
<GanttChart :tasks="tasks" :task-list-config="taskListConfig" />
|
||||||
:tasks="tasks"
|
|
||||||
:task-list-config="taskListConfig"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -1347,10 +1357,7 @@ Based on business requirements, you can customize columns to display, column wid
|
|||||||
|
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<GanttChart
|
<GanttChart :tasks="tasks" :task-list-config="taskListConfig" />
|
||||||
:tasks="tasks"
|
|
||||||
:task-list-config="taskListConfig"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -1435,10 +1442,7 @@ Combine `ref` and `computed` to achieve dynamic show/hide and width adjustment o
|
|||||||
|
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<GanttChart
|
<GanttChart :tasks="tasks" :task-list-config="taskListConfig" />
|
||||||
:tasks="tasks"
|
|
||||||
:task-list-config="taskListConfig"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -1477,6 +1481,7 @@ const taskListConfig = computed<TaskListConfig>(() => ({
|
|||||||
```
|
```
|
||||||
|
|
||||||
> **💡 Configuration Notes**:
|
> **💡 Configuration Notes**:
|
||||||
|
>
|
||||||
> - **Default behavior**:When not passed, show all 8 default columns with width of 320px
|
> - **Default behavior**:When not passed, show all 8 default columns with width of 320px
|
||||||
> - **Width units**:Supports pixel (`number`) and percentage (`string`, like `'30%'`) methods
|
> - **Width units**:Supports pixel (`number`) and percentage (`string`, like `'30%'`) methods
|
||||||
> - **Percentage calculation**:Based on total width of Gantt chart container, responsive adjustment
|
> - **Percentage calculation**:Based on total width of Gantt chart container, responsive adjustment
|
||||||
@@ -1493,7 +1498,7 @@ Controls task bar display content and interaction behavior。
|
|||||||
**Configuration Fields:**
|
**Configuration Fields:**
|
||||||
|
|
||||||
| Field | Type | Default | Description |
|
| Field | Type | Default | Description |
|
||||||
|--------|------|--------|------|
|
| ------------------- | --------- | ------- | --------------------------------------------------------- |
|
||||||
| `showAvatar` | `boolean` | `true` | Whether to show avatar |
|
| `showAvatar` | `boolean` | `true` | Whether to show avatar |
|
||||||
| `showTitle` | `boolean` | `true` | Whether to show title text |
|
| `showTitle` | `boolean` | `true` | Whether to show title text |
|
||||||
| `showProgress` | `boolean` | `true` | Whether to show progress text |
|
| `showProgress` | `boolean` | `true` | Whether to show progress text |
|
||||||
@@ -1503,6 +1508,7 @@ Controls task bar display content and interaction behavior。
|
|||||||
| `dragDelayTime` | `number` | `150` | Drag delay time (milliseconds) |
|
| `dragDelayTime` | `number` | `150` | Drag delay time (milliseconds) |
|
||||||
|
|
||||||
> **💡 Edit Permission Control**:
|
> **💡 Edit Permission Control**:
|
||||||
|
>
|
||||||
> - **Global control**: Use `<GanttChart :allow-drag-and-resize="false" />` to disable drag/resize for all tasks
|
> - **Global control**: Use `<GanttChart :allow-drag-and-resize="false" />` to disable drag/resize for all tasks
|
||||||
> - **Individual task control**: Set task object `isEditable: false` property to control individual task
|
> - **Individual task control**: Set task object `isEditable: false` property to control individual task
|
||||||
|
|
||||||
@@ -1510,10 +1516,7 @@ Controls task bar display content and interaction behavior。
|
|||||||
|
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<GanttChart
|
<GanttChart :tasks="tasks" :task-bar-config="taskBarConfig" />
|
||||||
:tasks="tasks"
|
|
||||||
:task-bar-config="taskBarConfig"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -1539,10 +1542,7 @@ Disable edit operations for all tasks.
|
|||||||
|
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<GanttChart
|
<GanttChart :tasks="tasks" :allow-drag-and-resize="false" />
|
||||||
:tasks="tasks"
|
|
||||||
:allow-drag-and-resize="false"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -1608,6 +1608,7 @@ const taskBarConfig = computed<TaskBarConfig>(() => ({
|
|||||||
}))
|
}))
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Timeline Container Auto-Fill Configuration
|
#### Timeline Container Auto-Fill Configuration
|
||||||
|
|
||||||
The component has built-in intelligent timeline range calculation logic, ensuring that regardless of task data volume or task duration, the timeline always fills the container width, providing the best visual experience.
|
The component has built-in intelligent timeline range calculation logic, ensuring that regardless of task data volume or task duration, the timeline always fills the container width, providing the best visual experience.
|
||||||
@@ -1615,6 +1616,7 @@ The component has built-in intelligent timeline range calculation logic, ensurin
|
|||||||
**Core Design Principles:**
|
**Core Design Principles:**
|
||||||
|
|
||||||
1. **Base Buffer Mechanism**: Add fixed buffers based on the actual time range of tasks, varying by view type
|
1. **Base Buffer Mechanism**: Add fixed buffers based on the actual time range of tasks, varying by view type
|
||||||
|
|
||||||
- Hour view:±1 day task range
|
- Hour view:±1 day task range
|
||||||
- Day view: ±30 days before/after task range
|
- Day view: ±30 days before/after task range
|
||||||
- Week view: ±8 weeks (approx. 2 months) before/after task range
|
- Week view: ±8 weeks (approx. 2 months) before/after task range
|
||||||
@@ -1623,10 +1625,12 @@ The component has built-in intelligent timeline range calculation logic, ensurin
|
|||||||
- Year view: ±1 year before/after task range
|
- Year view: ±1 year before/after task range
|
||||||
|
|
||||||
2. **Container Width Adaptation**: After base buffering, if calculated timeline width is less than container width, automatically extend the range
|
2. **Container Width Adaptation**: After base buffering, if calculated timeline width is less than container width, automatically extend the range
|
||||||
|
|
||||||
- Calculate time units (days/weeks/months/quarters/years) needed for container
|
- Calculate time units (days/weeks/months/quarters/years) needed for container
|
||||||
- **Symmetrically extend** on both sides of base range to ensure timeline fills container
|
- **Symmetrically extend** on both sides of base range to ensure timeline fills container
|
||||||
|
|
||||||
3. **Empty Data Handling**: When no task data exists, calculate reasonable time range based on container width and time scale
|
3. **Empty Data Handling**: When no task data exists, calculate reasonable time range based on container width and time scale
|
||||||
|
|
||||||
- Center on current date
|
- Center on current date
|
||||||
- Dynamically calculate time span to display based on container width
|
- Dynamically calculate time span to display based on container width
|
||||||
- Ensure minimum display range (e.g., at least 60 days for day view, at least 20 weeks for week view)
|
- Ensure minimum display range (e.g., at least 60 days for day view, at least 20 weeks for week view)
|
||||||
@@ -1638,7 +1642,7 @@ The component has built-in intelligent timeline range calculation logic, ensurin
|
|||||||
**Calculation Pattern Reference Table:**
|
**Calculation Pattern Reference Table:**
|
||||||
|
|
||||||
| View | Unit Width | Base Buffer | Empty Data Min Range | Container Auto-Fill? |
|
| View | Unit Width | Base Buffer | Empty Data Min Range | Container Auto-Fill? |
|
||||||
|------|-----------|--------------|----------------------|----------------|
|
| ------------ | ------------------------- | ----------- | -------------------- | -------------------- |
|
||||||
| Hour View | 30px/hour | ±1 day | 3 days | ✅ |
|
| Hour View | 30px/hour | ±1 day | 3 days | ✅ |
|
||||||
| Day View | 30px/day | ±30 days | 60 days | ✅ |
|
| Day View | 30px/day | ±30 days | 60 days | ✅ |
|
||||||
| Week View | 60px/week | ±2 months | 20 weeks | ✅ |
|
| Week View | 60px/week | ±2 months | 20 weeks | ✅ |
|
||||||
@@ -1649,11 +1653,13 @@ The component has built-in intelligent timeline range calculation logic, ensurin
|
|||||||
**Practical Application Scenarios:**
|
**Practical Application Scenarios:**
|
||||||
|
|
||||||
- **Short-term Tasks** (e.g., 1-week project):
|
- **Short-term Tasks** (e.g., 1-week project):
|
||||||
|
|
||||||
- Won't result in narrow timeline, automatically extends to fill container
|
- Won't result in narrow timeline, automatically extends to fill container
|
||||||
- Day view: 1 week (7 days × 30px = 210px) → Extends to ≥1200px (approx. 40 days)
|
- Day view: 1 week (7 days × 30px = 210px) → Extends to ≥1200px (approx. 40 days)
|
||||||
- Week view: 1 week (60px) → Extends to ≥1200px (approx. 20 weeks)
|
- Week view: 1 week (60px) → Extends to ≥1200px (approx. 20 weeks)
|
||||||
|
|
||||||
- **Long-term Projects** (e.g., 2-year project):
|
- **Long-term Projects** (e.g., 2-year project):
|
||||||
|
|
||||||
- After adding fixed buffer, automatically adapts to container
|
- After adding fixed buffer, automatically adapts to container
|
||||||
- Month view: 24 months + buffer → Extends to container width if needed
|
- Month view: 24 months + buffer → Extends to container width if needed
|
||||||
- Quarter view: 8 quarters + buffer → Extends to container width if needed
|
- Quarter view: 8 quarters + buffer → Extends to container width if needed
|
||||||
@@ -1665,6 +1671,7 @@ The component has built-in intelligent timeline range calculation logic, ensurin
|
|||||||
- Quarter/Year view: Displays at least 5 years
|
- Quarter/Year view: Displays at least 5 years
|
||||||
|
|
||||||
> **💡 Automation Advantages**:
|
> **💡 Automation Advantages**:
|
||||||
|
>
|
||||||
> - No need to manually set `startDate` and `endDate`, component automatically calculates optimal range
|
> - No need to manually set `startDate` and `endDate`, component automatically calculates optimal range
|
||||||
> - Responsive to container width changes, timeline automatically recalculates
|
> - Responsive to container width changes, timeline automatically recalculates
|
||||||
> - Different views independently optimized, auto-adjusts to best display effect when switching views
|
> - Different views independently optimized, auto-adjusts to best display effect when switching views
|
||||||
@@ -1679,10 +1686,7 @@ Component has built-in light and dark themes, can switch via toolbar button, als
|
|||||||
|
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<GanttChart
|
<GanttChart :tasks="tasks" :on-theme-change="handleThemeChange" />
|
||||||
:tasks="tasks"
|
|
||||||
:on-theme-change="handleThemeChange"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -1751,10 +1755,7 @@ Component has built-in Chinese (zh-CN) and English (en-US), can switch via toolb
|
|||||||
|
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<GanttChart
|
<GanttChart :tasks="tasks" :on-language-change="handleLanguageChange" />
|
||||||
:tasks="tasks"
|
|
||||||
:on-language-change="handleLanguageChange"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -1772,10 +1773,7 @@ Override or extend default translations via `localeMessages` prop:
|
|||||||
|
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<GanttChart
|
<GanttChart :tasks="tasks" :locale-messages="customMessages" />
|
||||||
:tasks="tasks"
|
|
||||||
:locale-messages="customMessages"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -1832,6 +1830,7 @@ const customMessages = {
|
|||||||
```
|
```
|
||||||
|
|
||||||
> **💡 Tip**:
|
> **💡 Tip**:
|
||||||
|
>
|
||||||
> - `localeMessages` adopts **deep merge** strategy, only need to pass fields that need to be overridden
|
> - `localeMessages` adopts **deep merge** strategy, only need to pass fields that need to be overridden
|
||||||
> - supports nested objects, like `taskList.name`, `toolbar.addTask`, etc.
|
> - supports nested objects, like `taskList.name`, `toolbar.addTask`, etc.
|
||||||
> - For complete translation keys, please refer to built-in `messages['zh-CN']` object in component
|
> - For complete translation keys, please refer to built-in `messages['zh-CN']` object in component
|
||||||
@@ -1849,14 +1848,14 @@ Used to customize task display content in task list (TaskRow) and timeline (Task
|
|||||||
**Slot Parameters:**
|
**Slot Parameters:**
|
||||||
|
|
||||||
| Parameter | Type | Source | Description |
|
| Parameter | Type | Source | Description |
|
||||||
|--------|------|------|------|
|
| --------- | ---------------------------- | ------ | ----------------------------- |
|
||||||
| `type` | `'task-row'` \| `'task-bar'` | Common | Slot call position identifier |
|
| `type` | `'task-row'` \| `'task-bar'` | Common | Slot call position identifier |
|
||||||
| `task` | `Task` | Common | Current task object |
|
| `task` | `Task` | Common | Current task object |
|
||||||
|
|
||||||
**TaskRow specific parameters (when `type === 'task-row'`):**
|
**TaskRow specific parameters (when `type === 'task-row'`):**
|
||||||
|
|
||||||
| Parameter | Type | Description |
|
| Parameter | Type | Description |
|
||||||
|--------|------|------|
|
| ---------------- | -------------------------------- | ------------------------- |
|
||||||
| `isRowContent` | `boolean` | Identified as row content |
|
| `isRowContent` | `boolean` | Identified as row content |
|
||||||
| `level` | `number` | Task level |
|
| `level` | `number` | Task level |
|
||||||
| `indent` | `string` | Indent style |
|
| `indent` | `string` | Indent style |
|
||||||
@@ -1878,7 +1877,7 @@ Used to customize task display content in task list (TaskRow) and timeline (Task
|
|||||||
**TaskBar specific parameters (when `type === 'task-bar'`):**
|
**TaskBar specific parameters (when `type === 'task-bar'`):**
|
||||||
|
|
||||||
| Parameter | Type | Description |
|
| Parameter | Type | Description |
|
||||||
|--------|------|------|
|
| ------------------ | --------------- | ------------------------------------------------------------------------------------ |
|
||||||
| `status` | `object` | TaskStatus object, contains `type`, `color`, `bgColor`, `borderColor` |
|
| `status` | `object` | TaskStatus object, contains `type`, `color`, `bgColor`, `borderColor` |
|
||||||
| `statusType` | `string` | StatusType:`'completed'`, `'delayed'`, `'in-progress'`, `'not-started'`, `'parent'` |
|
| `statusType` | `string` | StatusType:`'completed'`, `'delayed'`, `'in-progress'`, `'not-started'`, `'parent'` |
|
||||||
| `isParent` | `boolean` | Whether parent task |
|
| `isParent` | `boolean` | Whether parent task |
|
||||||
@@ -1894,11 +1893,7 @@ Used to customize task display content in task list (TaskRow) and timeline (Task
|
|||||||
<GanttChart :tasks="tasks">
|
<GanttChart :tasks="tasks">
|
||||||
<template #custom-task-content="slotProps">
|
<template #custom-task-content="slotProps">
|
||||||
<!-- Render different content based on type -->
|
<!-- Render different content based on type -->
|
||||||
<CustomTaskContent
|
<CustomTaskContent :task="slotProps.task" :type="slotProps.type" :status="slotProps.status" />
|
||||||
:task="slotProps.task"
|
|
||||||
:type="slotProps.type"
|
|
||||||
:status="slotProps.status"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</GanttChart>
|
</GanttChart>
|
||||||
</template>
|
</template>
|
||||||
@@ -1916,8 +1911,8 @@ const tasks = ref<Task[]>([
|
|||||||
name: '<strong>Important Task</strong>',
|
name: '<strong>Important Task</strong>',
|
||||||
startDate: '2025-01-01',
|
startDate: '2025-01-01',
|
||||||
endDate: '2025-01-10',
|
endDate: '2025-01-10',
|
||||||
progress: 50
|
progress: 50,
|
||||||
}
|
},
|
||||||
])
|
])
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
@@ -1994,6 +1989,7 @@ const props = defineProps<Props>()
|
|||||||
```
|
```
|
||||||
|
|
||||||
> **💡 Usage Scenarios**:
|
> **💡 Usage Scenarios**:
|
||||||
|
>
|
||||||
> - Support HTML formatted task names
|
> - Support HTML formatted task names
|
||||||
> - Add custom icons, tags or badges
|
> - Add custom icons, tags or badges
|
||||||
> - Display different styles based on task status
|
> - Display different styles based on task status
|
||||||
@@ -2001,6 +1997,7 @@ const props = defineProps<Props>()
|
|||||||
> - Display additional business information
|
> - Display additional business information
|
||||||
|
|
||||||
> **⚠️ Notes**:
|
> **⚠️ Notes**:
|
||||||
|
>
|
||||||
> - Slot content will be rendered in both TaskRow and TaskBar
|
> - Slot content will be rendered in both TaskRow and TaskBar
|
||||||
> - Need to distinguish rendering position based on `type` parameter
|
> - Need to distinguish rendering position based on `type` parameter
|
||||||
> - TaskRow and TaskBar have different available space, need to adapt layout
|
> - TaskRow and TaskBar have different available space, need to adapt layout
|
||||||
|
|||||||
@@ -2,7 +2,10 @@
|
|||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://www.npmjs.com/package/jordium-gantt-vue3">
|
<a href="https://www.npmjs.com/package/jordium-gantt-vue3">
|
||||||
<img src="https://img.shields.io/npm/v/jordium-gantt-vue3.svg" alt="npm version">
|
<img src="https://img.shields.io/npm/v/jordium-gantt-vue3?style=flat-square" alt="npm version">
|
||||||
|
</a>
|
||||||
|
<a href="https://www.npmjs.com/package/jordium-gantt-vue3">
|
||||||
|
<img src="https://img.shields.io/npm/dt/jordium-gantt-vue3?style=flat-square" alt="npm total">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://opensource.org/licenses/MIT">
|
<a href="https://opensource.org/licenses/MIT">
|
||||||
<img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License">
|
<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'
|
|||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<div style="height: 600px;">
|
<div style="height: 600px;">
|
||||||
<GanttChart
|
<GanttChart :tasks="tasks" :milestones="milestones" />
|
||||||
:tasks="tasks"
|
|
||||||
:milestones="milestones"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -123,7 +123,7 @@ const tasks = ref([
|
|||||||
name: '项目启动',
|
name: '项目启动',
|
||||||
startDate: '2025-01-01',
|
startDate: '2025-01-01',
|
||||||
endDate: '2025-01-10',
|
endDate: '2025-01-10',
|
||||||
progress: 100
|
progress: 100,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
@@ -131,7 +131,7 @@ const tasks = ref([
|
|||||||
startDate: '2025-01-11',
|
startDate: '2025-01-11',
|
||||||
endDate: '2025-01-20',
|
endDate: '2025-01-20',
|
||||||
progress: 80,
|
progress: 80,
|
||||||
predecessor: [1]
|
predecessor: [1],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 3,
|
id: 3,
|
||||||
@@ -139,8 +139,8 @@ const tasks = ref([
|
|||||||
startDate: '2025-01-21',
|
startDate: '2025-01-21',
|
||||||
endDate: '2025-02-05',
|
endDate: '2025-02-05',
|
||||||
progress: 50,
|
progress: 50,
|
||||||
predecessor: [2]
|
predecessor: [2],
|
||||||
}
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
const milestones = ref([
|
const milestones = ref([
|
||||||
@@ -148,8 +148,8 @@ const milestones = ref([
|
|||||||
id: 101,
|
id: 101,
|
||||||
name: '项目立项',
|
name: '项目立项',
|
||||||
date: '2025-01-01',
|
date: '2025-01-01',
|
||||||
type: 'milestone'
|
type: 'milestone',
|
||||||
}
|
},
|
||||||
])
|
])
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
@@ -158,6 +158,7 @@ const milestones = ref([
|
|||||||
<span><strong>推荐使用 <a href="https://dovee.cc/a.php?anaxjgyz1ozZq2B">DOVE</a> VPN,快速、稳定。</strong></span> <span style="color:red;">(注意:请合法使用 VPN 资源)</span>
|
<span><strong>推荐使用 <a href="https://dovee.cc/a.php?anaxjgyz1ozZq2B">DOVE</a> VPN,快速、稳定。</strong></span> <span style="color:red;">(注意:请合法使用 VPN 资源)</span>
|
||||||
|
|
||||||
## 🌞 NPM包使用示例
|
## 🌞 NPM包使用示例
|
||||||
|
|
||||||
请参考项目下的npm-demo,这是一个独立的项目,可以使用IDE单独浏览和启动,运行前请安装element plus以及jordium-gantt-vue3插件包
|
请参考项目下的npm-demo,这是一个独立的项目,可以使用IDE单独浏览和启动,运行前请安装element plus以及jordium-gantt-vue3插件包
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -166,6 +167,7 @@ npm install element-plus
|
|||||||
npm install jordium-gantt-vue3
|
npm install jordium-gantt-vue3
|
||||||
npm run dev
|
npm run dev
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 组件指南
|
## 组件指南
|
||||||
@@ -177,7 +179,7 @@ npm run dev
|
|||||||
#### 基础属性
|
#### 基础属性
|
||||||
|
|
||||||
| 属性名 | 类型 | 默认值 | 说明 |
|
| 属性名 | 类型 | 默认值 | 说明 |
|
||||||
|--------|------|--------|------|
|
| --------------------------- | --------- | ------- | -------------------------------------------------------------- |
|
||||||
| `tasks` | `Task[]` | `[]` | 任务数据数组 |
|
| `tasks` | `Task[]` | `[]` | 任务数据数组 |
|
||||||
| `milestones` | `Task[]` | `[]` | 里程碑数据数组(注意:类型为 Task[],需设置 type='milestone') |
|
| `milestones` | `Task[]` | `[]` | 里程碑数据数组(注意:类型为 Task[],需设置 type='milestone') |
|
||||||
| `showToolbar` | `boolean` | `true` | 是否显示工具栏 |
|
| `showToolbar` | `boolean` | `true` | 是否显示工具栏 |
|
||||||
@@ -191,7 +193,7 @@ npm run dev
|
|||||||
完整的配置对象说明请参考 [⚙️ 配置与扩展](#⚙️-配置与扩展) 章节。
|
完整的配置对象说明请参考 [⚙️ 配置与扩展](#⚙️-配置与扩展) 章节。
|
||||||
|
|
||||||
| 属性名 | 类型 | 默认值 | 说明 |
|
| 属性名 | 类型 | 默认值 | 说明 |
|
||||||
|--------|------|--------|------|
|
| ---------------- | ---------------------------- | ----------------------------------------------------------------------- | ---------------- |
|
||||||
| `toolbarConfig` | `ToolbarConfig` | `{}` | 工具栏配置 |
|
| `toolbarConfig` | `ToolbarConfig` | `{}` | 工具栏配置 |
|
||||||
| `taskListConfig` | `TaskListConfig` | `undefined` | 任务列表配置 |
|
| `taskListConfig` | `TaskListConfig` | `undefined` | 任务列表配置 |
|
||||||
| `taskBarConfig` | `TaskBarConfig` | `undefined` | 任务条样式配置 |
|
| `taskBarConfig` | `TaskBarConfig` | `undefined` | 任务条样式配置 |
|
||||||
@@ -201,7 +203,7 @@ npm run dev
|
|||||||
#### 回调函数属性
|
#### 回调函数属性
|
||||||
|
|
||||||
| 属性名 | 类型 | 说明 |
|
| 属性名 | 类型 | 说明 |
|
||||||
|--------|------|------|
|
| -------------------- | ------------------------------------ | -------------------------------------------------------- |
|
||||||
| `onTodayLocate` | `() => void` | 工具栏"今天"按钮点击回调 |
|
| `onTodayLocate` | `() => void` | 工具栏"今天"按钮点击回调 |
|
||||||
| `onExportCsv` | `() => boolean \| void` | 工具栏"导出CSV"按钮点击回调,返回 `false` 可阻止默认导出 |
|
| `onExportCsv` | `() => boolean \| void` | 工具栏"导出CSV"按钮点击回调,返回 `false` 可阻止默认导出 |
|
||||||
| `onExportPdf` | `() => void` | 工具栏"导出PDF"按钮点击回调 |
|
| `onExportPdf` | `() => void` | 工具栏"导出PDF"按钮点击回调 |
|
||||||
@@ -214,13 +216,14 @@ npm run dev
|
|||||||
#### 组件事件(Events)
|
#### 组件事件(Events)
|
||||||
|
|
||||||
完整的事件说明请分别参考:
|
完整的事件说明请分别参考:
|
||||||
|
|
||||||
- **任务相关事件**:参见下方 [任务管理](#任务管理) 章节
|
- **任务相关事件**:参见下方 [任务管理](#任务管理) 章节
|
||||||
- **里程碑相关事件**:参见下方 [里程碑管理](#里程碑管理) 章节
|
- **里程碑相关事件**:参见下方 [里程碑管理](#里程碑管理) 章节
|
||||||
|
|
||||||
**事件列表总览:**
|
**事件列表总览:**
|
||||||
|
|
||||||
| 事件名 | 参数 | 说明 |
|
| 事件名 | 参数 | 说明 |
|
||||||
|--------|------|------|
|
| ------------------------ | --------------------------------- | -------------------------- |
|
||||||
| `add-task` | - | 点击工具栏"添加任务"按钮 |
|
| `add-task` | - | 点击工具栏"添加任务"按钮 |
|
||||||
| `task-click` | `(task: Task, event: MouseEvent)` | 点击任务 |
|
| `task-click` | `(task: Task, event: MouseEvent)` | 点击任务 |
|
||||||
| `task-double-click` | `(task: Task)` | 双击任务 |
|
| `task-double-click` | `(task: Task)` | 双击任务 |
|
||||||
@@ -259,8 +262,8 @@ const tasks = ref([
|
|||||||
name: '任务1',
|
name: '任务1',
|
||||||
startDate: '2025-01-01',
|
startDate: '2025-01-01',
|
||||||
endDate: '2025-01-10',
|
endDate: '2025-01-10',
|
||||||
progress: 100
|
progress: 100,
|
||||||
}
|
},
|
||||||
])
|
])
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
@@ -270,10 +273,7 @@ const tasks = ref([
|
|||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<div style="height: 600px;">
|
<div style="height: 600px;">
|
||||||
<GanttChart
|
<GanttChart :tasks="tasks" :milestones="milestones" />
|
||||||
:tasks="tasks"
|
|
||||||
:milestones="milestones"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -288,8 +288,8 @@ const tasks = ref([
|
|||||||
name: '项目启动',
|
name: '项目启动',
|
||||||
startDate: '2025-01-01',
|
startDate: '2025-01-01',
|
||||||
endDate: '2025-01-10',
|
endDate: '2025-01-10',
|
||||||
progress: 100
|
progress: 100,
|
||||||
}
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
const milestones = ref([
|
const milestones = ref([
|
||||||
@@ -298,8 +298,8 @@ const milestones = ref([
|
|||||||
name: '项目立项',
|
name: '项目立项',
|
||||||
startDate: '2025-01-01',
|
startDate: '2025-01-01',
|
||||||
type: 'milestone',
|
type: 'milestone',
|
||||||
icon: 'diamond'
|
icon: 'diamond',
|
||||||
}
|
},
|
||||||
])
|
])
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
@@ -342,7 +342,7 @@ const addTask = () => {
|
|||||||
name: '新任务',
|
name: '新任务',
|
||||||
startDate: new Date().toISOString().split('T')[0],
|
startDate: new Date().toISOString().split('T')[0],
|
||||||
endDate: new Date().toISOString().split('T')[0],
|
endDate: new Date().toISOString().split('T')[0],
|
||||||
progress: 0
|
progress: 0,
|
||||||
}
|
}
|
||||||
tasks.value.push(newTask)
|
tasks.value.push(newTask)
|
||||||
}
|
}
|
||||||
@@ -352,16 +352,16 @@ const addMilestone = () => {
|
|||||||
id: Date.now(),
|
id: Date.now(),
|
||||||
name: '新里程碑',
|
name: '新里程碑',
|
||||||
startDate: new Date().toISOString().split('T')[0],
|
startDate: new Date().toISOString().split('T')[0],
|
||||||
type: 'milestone'
|
type: 'milestone',
|
||||||
}
|
}
|
||||||
milestones.value.push(newMilestone)
|
milestones.value.push(newMilestone)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleTaskAdded = (e) => {
|
const handleTaskAdded = e => {
|
||||||
console.log('任务已添加:', e.task)
|
console.log('任务已添加:', e.task)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleMilestoneSaved = (milestone) => {
|
const handleMilestoneSaved = milestone => {
|
||||||
console.log('里程碑已保存:', milestone)
|
console.log('里程碑已保存:', milestone)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -376,7 +376,7 @@ const handleMilestoneSaved = (milestone) => {
|
|||||||
#### Task 数据结构
|
#### Task 数据结构
|
||||||
|
|
||||||
| 字段名 | 类型 | 必填 | 默认值 | 说明 |
|
| 字段名 | 类型 | 必填 | 默认值 | 说明 |
|
||||||
|--------|------|------|--------|------|
|
| ------------------ | ---------- | ---- | ----------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `id` | `number` | ✅ | - | 任务唯一标识符 |
|
| `id` | `number` | ✅ | - | 任务唯一标识符 |
|
||||||
| `name` | `string` | ✅ | - | 任务名称 |
|
| `name` | `string` | ✅ | - | 任务名称 |
|
||||||
| `startDate` | `string` | - | - | 开始日期,格式:'YYYY-MM-DD' 或 'YYYY-MM-DD HH:mm' |
|
| `startDate` | `string` | - | - | 开始日期,格式:'YYYY-MM-DD' 或 'YYYY-MM-DD HH:mm' |
|
||||||
@@ -406,6 +406,7 @@ const handleMilestoneSaved = (milestone) => {
|
|||||||
> **自定义属性扩展**:Task 接口支持添加任意自定义字段,例如:`priority`、`tags`、`status`、`department` 等业务相关字段。
|
> **自定义属性扩展**:Task 接口支持添加任意自定义字段,例如:`priority`、`tags`、`status`、`department` 等业务相关字段。
|
||||||
>
|
>
|
||||||
> **前置任务字段说明**:
|
> **前置任务字段说明**:
|
||||||
|
>
|
||||||
> - **标准格式**(推荐):`predecessor: [1, 2, 3]` - number 数组
|
> - **标准格式**(推荐):`predecessor: [1, 2, 3]` - number 数组
|
||||||
> - **兼容格式1**:`predecessor: '1,2,3'` - 逗号分隔的字符串
|
> - **兼容格式1**:`predecessor: '1,2,3'` - 逗号分隔的字符串
|
||||||
> - **兼容格式2**:`predecessor: ['1', '2', '3']` - 字符串数组
|
> - **兼容格式2**:`predecessor: ['1', '2', '3']` - 字符串数组
|
||||||
@@ -415,7 +416,7 @@ const handleMilestoneSaved = (milestone) => {
|
|||||||
#### 任务相关属性
|
#### 任务相关属性
|
||||||
|
|
||||||
| 属性名 | 类型 | 默认值 | 说明 |
|
| 属性名 | 类型 | 默认值 | 说明 |
|
||||||
|--------|------|--------|------|
|
| --------------------- | ---------------- | ----------- | -------------------------------------------------------------- |
|
||||||
| `tasks` | `Task[]` | `[]` | 任务数据数组 |
|
| `tasks` | `Task[]` | `[]` | 任务数据数组 |
|
||||||
| `useDefaultDrawer` | `boolean` | `true` | 是否使用内置的任务编辑抽屉(TaskDrawer) |
|
| `useDefaultDrawer` | `boolean` | `true` | 是否使用内置的任务编辑抽屉(TaskDrawer) |
|
||||||
| `taskBarConfig` | `TaskBarConfig` | `{}` | 任务条样式配置,详见 [TaskBarConfig 配置](#taskbarconfig-配置) |
|
| `taskBarConfig` | `TaskBarConfig` | `{}` | 任务条样式配置,详见 [TaskBarConfig 配置](#taskbarconfig-配置) |
|
||||||
@@ -423,6 +424,7 @@ const handleMilestoneSaved = (milestone) => {
|
|||||||
| `autoSortByStartDate` | `boolean` | `false` | 是否根据开始时间自动排序任务 |
|
| `autoSortByStartDate` | `boolean` | `false` | 是否根据开始时间自动排序任务 |
|
||||||
|
|
||||||
**配置说明**:
|
**配置说明**:
|
||||||
|
|
||||||
- **默认模式**:`useDefaultDrawer=true`(默认),双击任务自动打开内置 TaskDrawer
|
- **默认模式**:`useDefaultDrawer=true`(默认),双击任务自动打开内置 TaskDrawer
|
||||||
- **自定义编辑器**:`useDefaultDrawer=false` 禁用内置抽屉,监听 `@task-double-click` 事件打开自定义编辑器
|
- **自定义编辑器**:`useDefaultDrawer=false` 禁用内置抽屉,监听 `@task-double-click` 事件打开自定义编辑器
|
||||||
- **只读模式**:`useDefaultDrawer=false` 且不监听 `@task-double-click` 事件,用户双击任务无反应
|
- **只读模式**:`useDefaultDrawer=false` 且不监听 `@task-double-click` 事件,用户双击任务无反应
|
||||||
@@ -432,7 +434,7 @@ const handleMilestoneSaved = (milestone) => {
|
|||||||
> **💡 事件驱动架构**:组件采用纯事件驱动设计,所有用户操作(添加、编辑、删除、拖拽等)都会触发对应事件,方便外部监听和处理。
|
> **💡 事件驱动架构**:组件采用纯事件驱动设计,所有用户操作(添加、编辑、删除、拖拽等)都会触发对应事件,方便外部监听和处理。
|
||||||
|
|
||||||
| 事件名 | 参数 | 触发时机 | 说明 |
|
| 事件名 | 参数 | 触发时机 | 说明 |
|
||||||
|--------|------|---------|------|
|
| -------------------- | ----------------------------------------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `add-task` | - | 点击工具栏"添加任务"按钮时 | 可用于自定义新增任务逻辑。如 `useDefaultDrawer=true`,组件会自动打开内置 TaskDrawer |
|
| `add-task` | - | 点击工具栏"添加任务"按钮时 | 可用于自定义新增任务逻辑。如 `useDefaultDrawer=true`,组件会自动打开内置 TaskDrawer |
|
||||||
| `task-click` | `(task: Task, event: MouseEvent) => void` | 点击任务条时 | 单击任务触发 |
|
| `task-click` | `(task: Task, event: MouseEvent) => void` | 点击任务条时 | 单击任务触发 |
|
||||||
| `task-double-click` | `(task: Task) => void` | 双击任务条时 | 双击任务时**始终触发**。`useDefaultDrawer=true` 时组件会额外打开内置编辑器,`false` 时不打开。事件触发与属性值无关 |
|
| `task-double-click` | `(task: Task) => void` | 双击任务条时 | 双击任务时**始终触发**。`useDefaultDrawer=true` 时组件会额外打开内置编辑器,`false` 时不打开。事件触发与属性值无关 |
|
||||||
@@ -447,6 +449,7 @@ const handleMilestoneSaved = (milestone) => {
|
|||||||
| `timer-stopped` | `(task: Task) => void` | 任务计时器停止时 | 停止记录任务工时 |
|
| `timer-stopped` | `(task: Task) => void` | 任务计时器停止时 | 停止记录任务工时 |
|
||||||
|
|
||||||
**数据同步说明**:
|
**数据同步说明**:
|
||||||
|
|
||||||
- ✅ **组件内部自动更新**:所有任务的增删改操作,组件都会自动更新 `props.tasks` 数据
|
- ✅ **组件内部自动更新**:所有任务的增删改操作,组件都会自动更新 `props.tasks` 数据
|
||||||
- ✅ **事件仅做通知**:外部监听事件主要用于:显示提示消息、调用后端 API、更新其他相关数据等
|
- ✅ **事件仅做通知**:外部监听事件主要用于:显示提示消息、调用后端 API、更新其他相关数据等
|
||||||
- ❌ **避免重复操作**:不要在事件处理器中再次修改 `tasks` 数据,否则会导致重复更新
|
- ❌ **避免重复操作**:不要在事件处理器中再次修改 `tasks` 数据,否则会导致重复更新
|
||||||
@@ -492,7 +495,7 @@ const tasks = ref<Task[]>([
|
|||||||
progress: 60,
|
progress: 60,
|
||||||
assignee: '李四',
|
assignee: '李四',
|
||||||
predecessor: [1], // 依赖任务1
|
predecessor: [1], // 依赖任务1
|
||||||
}
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
// 工具栏"添加任务"按钮点击事件
|
// 工具栏"添加任务"按钮点击事件
|
||||||
@@ -565,7 +568,7 @@ const tasks = ref<Task[]>([
|
|||||||
startDate: '2025-01-01',
|
startDate: '2025-01-01',
|
||||||
endDate: '2025-01-10',
|
endDate: '2025-01-10',
|
||||||
progress: 100,
|
progress: 100,
|
||||||
predecessor: [] // 无前置任务
|
predecessor: [], // 无前置任务
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
@@ -573,7 +576,7 @@ const tasks = ref<Task[]>([
|
|||||||
startDate: '2025-01-11',
|
startDate: '2025-01-11',
|
||||||
endDate: '2025-01-20',
|
endDate: '2025-01-20',
|
||||||
progress: 80,
|
progress: 80,
|
||||||
predecessor: [1] // 依赖任务1(需求分析)
|
predecessor: [1], // 依赖任务1(需求分析)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 3,
|
id: 3,
|
||||||
@@ -581,7 +584,7 @@ const tasks = ref<Task[]>([
|
|||||||
startDate: '2025-01-11',
|
startDate: '2025-01-11',
|
||||||
endDate: '2025-01-18',
|
endDate: '2025-01-18',
|
||||||
progress: 90,
|
progress: 90,
|
||||||
predecessor: [1] // 依赖任务1
|
predecessor: [1], // 依赖任务1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 4,
|
id: 4,
|
||||||
@@ -589,7 +592,7 @@ const tasks = ref<Task[]>([
|
|||||||
startDate: '2025-01-21',
|
startDate: '2025-01-21',
|
||||||
endDate: '2025-02-10',
|
endDate: '2025-02-10',
|
||||||
progress: 60,
|
progress: 60,
|
||||||
predecessor: [2] // 依赖任务2(系统设计)
|
predecessor: [2], // 依赖任务2(系统设计)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 5,
|
id: 5,
|
||||||
@@ -597,7 +600,7 @@ const tasks = ref<Task[]>([
|
|||||||
startDate: '2025-01-19',
|
startDate: '2025-01-19',
|
||||||
endDate: '2025-02-08',
|
endDate: '2025-02-08',
|
||||||
progress: 70,
|
progress: 70,
|
||||||
predecessor: [2, 3] // 同时依赖任务2和3
|
predecessor: [2, 3], // 同时依赖任务2和3
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 6,
|
id: 6,
|
||||||
@@ -605,8 +608,8 @@ const tasks = ref<Task[]>([
|
|||||||
startDate: '2025-02-11',
|
startDate: '2025-02-11',
|
||||||
endDate: '2025-02-20',
|
endDate: '2025-02-20',
|
||||||
progress: 30,
|
progress: 30,
|
||||||
predecessor: [4, 5] // 依赖前端和后端开发完成
|
predecessor: [4, 5], // 依赖前端和后端开发完成
|
||||||
}
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
// 通过右键菜单添加前置任务时触发
|
// 通过右键菜单添加前置任务时触发
|
||||||
@@ -628,6 +631,7 @@ const handleSuccessorAdded = (event: { targetTask: Task; newTask: Task }) => {
|
|||||||
```
|
```
|
||||||
|
|
||||||
**依赖关系说明**:
|
**依赖关系说明**:
|
||||||
|
|
||||||
- **`predecessor` 字段支持多种格式**:
|
- **`predecessor` 字段支持多种格式**:
|
||||||
- 标准格式(推荐):`[1, 2, 3]` - number 数组
|
- 标准格式(推荐):`[1, 2, 3]` - number 数组
|
||||||
- 兼容格式1:`'1,2,3'` - 逗号分隔的字符串
|
- 兼容格式1:`'1,2,3'` - 逗号分隔的字符串
|
||||||
@@ -696,7 +700,7 @@ const handleAddMilestone = () => {
|
|||||||
console.log('准备新增里程碑(由自定义按钮触发)')
|
console.log('准备新增里程碑(由自定义按钮触发)')
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleTaskAdded = (e) => {
|
const handleTaskAdded = e => {
|
||||||
console.log('任务已添加:', e.task)
|
console.log('任务已添加:', e.task)
|
||||||
// 调用 API 保存...
|
// 调用 API 保存...
|
||||||
}
|
}
|
||||||
@@ -704,6 +708,7 @@ const handleTaskAdded = (e) => {
|
|||||||
```
|
```
|
||||||
|
|
||||||
> **💡 灵活性设计**:
|
> **💡 灵活性设计**:
|
||||||
|
>
|
||||||
> - 显示工具栏 + 默认编辑器:最简单的开箱即用方式
|
> - 显示工具栏 + 默认编辑器:最简单的开箱即用方式
|
||||||
> - 隐藏工具栏 + 自定义按钮 + 默认编辑器:自定义控制栏样式,保留默认编辑功能
|
> - 隐藏工具栏 + 自定义按钮 + 默认编辑器:自定义控制栏样式,保留默认编辑功能
|
||||||
> - 隐藏工具栏 + 自定义按钮 + 自定义编辑器:完全自定义所有交互逻辑
|
> - 隐藏工具栏 + 自定义按钮 + 自定义编辑器:完全自定义所有交互逻辑
|
||||||
@@ -717,7 +722,7 @@ const handleTaskAdded = (e) => {
|
|||||||
#### Milestone 数据结构
|
#### Milestone 数据结构
|
||||||
|
|
||||||
| 字段名 | 类型 | 必填 | 默认值 | 说明 |
|
| 字段名 | 类型 | 必填 | 默认值 | 说明 |
|
||||||
|--------|------|------|--------|------|
|
| ------------- | -------- | ---- | ------------- | ---------------------------------------------------------- |
|
||||||
| `id` | `number` | ✅ | - | 里程碑唯一标识符 |
|
| `id` | `number` | ✅ | - | 里程碑唯一标识符 |
|
||||||
| `name` | `string` | ✅ | - | 里程碑名称 |
|
| `name` | `string` | ✅ | - | 里程碑名称 |
|
||||||
| `startDate` | `string` | ✅ | - | 里程碑日期,格式:'YYYY-MM-DD' 或 'YYYY-MM-DD HH:mm' |
|
| `startDate` | `string` | ✅ | - | 里程碑日期,格式:'YYYY-MM-DD' 或 'YYYY-MM-DD HH:mm' |
|
||||||
@@ -732,16 +737,18 @@ const handleTaskAdded = (e) => {
|
|||||||
#### 里程碑相关属性
|
#### 里程碑相关属性
|
||||||
|
|
||||||
| 属性名 | 类型 | 默认值 | 说明 |
|
| 属性名 | 类型 | 默认值 | 说明 |
|
||||||
|--------|------|--------|------|
|
| --------------------------- | --------- | ------ | -------------------------------------------------------- |
|
||||||
| `milestones` | `Task[]` | `[]` | 里程碑数据数组(类型为 Task[],需确保 type='milestone') |
|
| `milestones` | `Task[]` | `[]` | 里程碑数据数组(类型为 Task[],需确保 type='milestone') |
|
||||||
| `useDefaultMilestoneDialog` | `boolean` | `true` | 是否使用内置的里程碑编辑对话框(MilestoneDialog) |
|
| `useDefaultMilestoneDialog` | `boolean` | `true` | 是否使用内置的里程碑编辑对话框(MilestoneDialog) |
|
||||||
|
|
||||||
**配置说明**:
|
**配置说明**:
|
||||||
|
|
||||||
- **默认模式**:`useDefaultMilestoneDialog=true`(默认),双击里程碑自动打开内置 MilestoneDialog
|
- **默认模式**:`useDefaultMilestoneDialog=true`(默认),双击里程碑自动打开内置 MilestoneDialog
|
||||||
- **禁用编辑器**:`useDefaultMilestoneDialog=false`,双击里程碑无反应(组件不打开任何编辑器)
|
- **禁用编辑器**:`useDefaultMilestoneDialog=false`,双击里程碑无反应(组件不打开任何编辑器)
|
||||||
- **自定义编辑器**:可以监听 `onMilestoneDoubleClick` 回调或相关事件,实现自定义编辑逻辑
|
- **自定义编辑器**:可以监听 `onMilestoneDoubleClick` 回调或相关事件,实现自定义编辑逻辑
|
||||||
|
|
||||||
> **💡 里程碑与任务的区别**:
|
> **💡 里程碑与任务的区别**:
|
||||||
|
>
|
||||||
> - 里程碑数据通过 `milestones` 属性独立管理,与 `tasks` 分开
|
> - 里程碑数据通过 `milestones` 属性独立管理,与 `tasks` 分开
|
||||||
> - 里程碑对象的 `type` 字段必须设置为 `'milestone'`
|
> - 里程碑对象的 `type` 字段必须设置为 `'milestone'`
|
||||||
> - 里程碑不支持子任务、依赖关系等复杂结构
|
> - 里程碑不支持子任务、依赖关系等复杂结构
|
||||||
@@ -751,13 +758,12 @@ const handleTaskAdded = (e) => {
|
|||||||
|
|
||||||
> **⚠️ 已废弃**:请使用新的事件驱动 API(见下方"里程碑事件"章节)
|
> **⚠️ 已废弃**:请使用新的事件驱动 API(见下方"里程碑事件"章节)
|
||||||
|
|
||||||
|
|
||||||
#### 里程碑事件
|
#### 里程碑事件
|
||||||
|
|
||||||
> **💡 事件驱动架构**:里程碑管理采用事件驱动设计,推荐使用事件 API 替代回调函数。
|
> **💡 事件驱动架构**:里程碑管理采用事件驱动设计,推荐使用事件 API 替代回调函数。
|
||||||
|
|
||||||
| 事件名 | 参数 | 触发时机 | 说明 |
|
| 事件名 | 参数 | 触发时机 | 说明 |
|
||||||
|--------|------|---------|------|
|
| ------------------------ | --------------------------------------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `add-milestone` | - | 点击工具栏"添加里程碑"按钮时 | 可用于自定义新增里程碑逻辑。如 `useDefaultMilestoneDialog=true`,组件会自动打开内置 MilestoneDialog |
|
| `add-milestone` | - | 点击工具栏"添加里程碑"按钮时 | 可用于自定义新增里程碑逻辑。如 `useDefaultMilestoneDialog=true`,组件会自动打开内置 MilestoneDialog |
|
||||||
| `milestone-saved` | `(milestone: Task) => void` | 里程碑保存后(新增或编辑) | 通过内置 MilestoneDialog 保存里程碑后触发。**注意**:组件已自动更新 `milestones` 数据,外部只需监听此事件做额外处理(如调用 API 保存) |
|
| `milestone-saved` | `(milestone: Task) => void` | 里程碑保存后(新增或编辑) | 通过内置 MilestoneDialog 保存里程碑后触发。**注意**:组件已自动更新 `milestones` 数据,外部只需监听此事件做额外处理(如调用 API 保存) |
|
||||||
| `milestone-deleted` | `{ milestoneId: number }` | 里程碑删除后 | 通过内置 MilestoneDialog 删除里程碑后触发。**注意**:组件已自动更新 `milestones` 数据,外部只需监听此事件做额外处理 |
|
| `milestone-deleted` | `{ milestoneId: number }` | 里程碑删除后 | 通过内置 MilestoneDialog 删除里程碑后触发。**注意**:组件已自动更新 `milestones` 数据,外部只需监听此事件做额外处理 |
|
||||||
@@ -765,6 +771,7 @@ const handleTaskAdded = (e) => {
|
|||||||
| `milestone-drag-end` | `(milestone: Task) => void` | 拖拽里程碑结束时 | 里程碑日期已更新。**注意**:组件已自动更新 `milestones` 数据 |
|
| `milestone-drag-end` | `(milestone: Task) => void` | 拖拽里程碑结束时 | 里程碑日期已更新。**注意**:组件已自动更新 `milestones` 数据 |
|
||||||
|
|
||||||
**数据同步说明**:
|
**数据同步说明**:
|
||||||
|
|
||||||
- ✅ **组件内部自动更新**:所有里程碑的增删改操作,组件都会自动更新 `props.milestones` 数据
|
- ✅ **组件内部自动更新**:所有里程碑的增删改操作,组件都会自动更新 `props.milestones` 数据
|
||||||
- ✅ **事件仅做通知**:外部监听事件主要用于:显示提示消息、调用后端 API、更新其他相关数据等
|
- ✅ **事件仅做通知**:外部监听事件主要用于:显示提示消息、调用后端 API、更新其他相关数据等
|
||||||
- ❌ **避免重复操作**:不要在事件处理器中再次修改 `milestones` 数据,否则会导致重复更新
|
- ❌ **避免重复操作**:不要在事件处理器中再次修改 `milestones` 数据,否则会导致重复更新
|
||||||
@@ -801,15 +808,15 @@ const milestones = ref<Task[]>([
|
|||||||
type: 'milestone',
|
type: 'milestone',
|
||||||
icon: 'diamond',
|
icon: 'diamond',
|
||||||
assignee: '项目经理',
|
assignee: '项目经理',
|
||||||
description: '项目正式启动'
|
description: '项目正式启动',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 102,
|
id: 102,
|
||||||
name: '需求评审',
|
name: '需求评审',
|
||||||
startDate: '2025-01-15',
|
startDate: '2025-01-15',
|
||||||
type: 'milestone',
|
type: 'milestone',
|
||||||
icon: 'flag'
|
icon: 'flag',
|
||||||
}
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
// 工具栏"添加里程碑"按钮点击事件
|
// 工具栏"添加里程碑"按钮点击事件
|
||||||
@@ -892,8 +899,8 @@ const milestones = ref<Task[]>([
|
|||||||
type: 'milestone',
|
type: 'milestone',
|
||||||
icon: 'diamond',
|
icon: 'diamond',
|
||||||
assignee: '项目经理',
|
assignee: '项目经理',
|
||||||
description: '项目正式启动'
|
description: '项目正式启动',
|
||||||
}
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
const customDialogVisible = ref(false)
|
const customDialogVisible = ref(false)
|
||||||
@@ -923,7 +930,7 @@ const handleCustomDialogSave = (milestone: Task) => {
|
|||||||
const newMilestone = {
|
const newMilestone = {
|
||||||
...milestone,
|
...milestone,
|
||||||
id: Date.now(), // 生成新 ID
|
id: Date.now(), // 生成新 ID
|
||||||
type: 'milestone'
|
type: 'milestone',
|
||||||
}
|
}
|
||||||
milestones.value.push(newMilestone)
|
milestones.value.push(newMilestone)
|
||||||
|
|
||||||
@@ -1013,20 +1020,13 @@ const handleMilestoneDrag = (milestone: Task) => {
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="描述">
|
<el-form-item label="描述">
|
||||||
<el-input
|
<el-input v-model="form.description" type="textarea" :rows="3" placeholder="请输入描述" />
|
||||||
v-model="form.description"
|
|
||||||
type="textarea"
|
|
||||||
:rows="3"
|
|
||||||
placeholder="请输入描述"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button v-if="!isNew" type="danger" @click="handleDelete">
|
<el-button v-if="!isNew" type="danger" @click="handleDelete"> 删除 </el-button>
|
||||||
删除
|
|
||||||
</el-button>
|
|
||||||
<el-button @click="handleClose">取消</el-button>
|
<el-button @click="handleClose">取消</el-button>
|
||||||
<el-button type="primary" @click="handleSave">保存</el-button>
|
<el-button type="primary" @click="handleSave">保存</el-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -1059,10 +1059,12 @@ const form = ref({
|
|||||||
assignee: '',
|
assignee: '',
|
||||||
icon: 'diamond',
|
icon: 'diamond',
|
||||||
description: '',
|
description: '',
|
||||||
type: 'milestone'
|
type: 'milestone',
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(() => props.visible, (val) => {
|
watch(
|
||||||
|
() => props.visible,
|
||||||
|
val => {
|
||||||
dialogVisible.value = val
|
dialogVisible.value = val
|
||||||
if (val) {
|
if (val) {
|
||||||
if (props.milestone) {
|
if (props.milestone) {
|
||||||
@@ -1077,13 +1079,14 @@ watch(() => props.visible, (val) => {
|
|||||||
assignee: '',
|
assignee: '',
|
||||||
icon: 'diamond',
|
icon: 'diamond',
|
||||||
description: '',
|
description: '',
|
||||||
type: 'milestone'
|
type: 'milestone',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
watch(dialogVisible, (val) => {
|
watch(dialogVisible, val => {
|
||||||
emit('update:visible', val)
|
emit('update:visible', val)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -1108,6 +1111,7 @@ const handleDelete = () => {
|
|||||||
```
|
```
|
||||||
|
|
||||||
> **💡 自定义对话框说明**:
|
> **💡 自定义对话框说明**:
|
||||||
|
>
|
||||||
> - 设置 `use-default-milestone-dialog="false"` 禁用内置对话框
|
> - 设置 `use-default-milestone-dialog="false"` 禁用内置对话框
|
||||||
> - 监听 `@add-milestone` 事件打开自定义对话框
|
> - 监听 `@add-milestone` 事件打开自定义对话框
|
||||||
> - 需要手动管理 `milestones` 数组的增删改
|
> - 需要手动管理 `milestones` 数组的增删改
|
||||||
@@ -1129,7 +1133,7 @@ const handleDelete = () => {
|
|||||||
**类型定义:**
|
**类型定义:**
|
||||||
|
|
||||||
| 字段名 | 类型 | 默认值 | 说明 |
|
| 字段名 | 类型 | 默认值 | 说明 |
|
||||||
|--------|------|--------|------|
|
| --------------------- | ----------------- | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
|
||||||
| `showAddTask` | `boolean` | `true` | 显示"添加任务"按钮 |
|
| `showAddTask` | `boolean` | `true` | 显示"添加任务"按钮 |
|
||||||
| `showAddMilestone` | `boolean` | `true` | 显示"添加里程碑"按钮 |
|
| `showAddMilestone` | `boolean` | `true` | 显示"添加里程碑"按钮 |
|
||||||
| `showTodayLocate` | `boolean` | `true` | 显示"定位到今天"按钮 |
|
| `showTodayLocate` | `boolean` | `true` | 显示"定位到今天"按钮 |
|
||||||
@@ -1163,10 +1167,7 @@ TimelineScale.YEAR // 'year' - 年视图
|
|||||||
|
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<GanttChart
|
<GanttChart :tasks="tasks" :toolbar-config="toolbarConfig" />
|
||||||
:tasks="tasks"
|
|
||||||
:toolbar-config="toolbarConfig"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -1184,11 +1185,17 @@ const toolbarConfig: ToolbarConfig = {
|
|||||||
showTheme: true, // 显示主题切换按钮
|
showTheme: true, // 显示主题切换按钮
|
||||||
showFullscreen: true, // 显示全屏按钮
|
showFullscreen: true, // 显示全屏按钮
|
||||||
showTimeScale: true, // 显示时间刻度按钮组
|
showTimeScale: true, // 显示时间刻度按钮组
|
||||||
timeScaleDimensions: [ // 显示所有时间刻度维度
|
timeScaleDimensions: [
|
||||||
'hour', 'day', 'week', 'month', 'quarter', 'year'
|
// 显示所有时间刻度维度
|
||||||
|
'hour',
|
||||||
|
'day',
|
||||||
|
'week',
|
||||||
|
'month',
|
||||||
|
'quarter',
|
||||||
|
'year',
|
||||||
],
|
],
|
||||||
defaultTimeScale: 'week', // 默认选中周视图
|
defaultTimeScale: 'week', // 默认选中周视图
|
||||||
showExpandCollapse: true // 显示展开/折叠按钮
|
showExpandCollapse: true, // 显示展开/折叠按钮
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
@@ -1209,11 +1216,14 @@ const toolbarConfig: ToolbarConfig = {
|
|||||||
showTheme: true, // 保留主题切换
|
showTheme: true, // 保留主题切换
|
||||||
showFullscreen: true, // 保留全屏
|
showFullscreen: true, // 保留全屏
|
||||||
showTimeScale: true, // 显示时间刻度
|
showTimeScale: true, // 显示时间刻度
|
||||||
timeScaleDimensions: [ // 只显示日/周/月三种刻度
|
timeScaleDimensions: [
|
||||||
'day', 'week', 'month'
|
// 只显示日/周/月三种刻度
|
||||||
|
'day',
|
||||||
|
'week',
|
||||||
|
'month',
|
||||||
],
|
],
|
||||||
defaultTimeScale: 'week', // 默认周视图
|
defaultTimeScale: 'week', // 默认周视图
|
||||||
showExpandCollapse: true // 保留展开/折叠
|
showExpandCollapse: true, // 保留展开/折叠
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
@@ -1231,9 +1241,9 @@ const toolbarConfig: ToolbarConfig = {
|
|||||||
TimelineScale.DAY,
|
TimelineScale.DAY,
|
||||||
TimelineScale.WEEK,
|
TimelineScale.WEEK,
|
||||||
TimelineScale.MONTH,
|
TimelineScale.MONTH,
|
||||||
TimelineScale.QUARTER
|
TimelineScale.QUARTER,
|
||||||
],
|
],
|
||||||
defaultTimeScale: TimelineScale.MONTH // 默认月视图
|
defaultTimeScale: TimelineScale.MONTH, // 默认月视图
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
@@ -1256,12 +1266,13 @@ const toolbarConfig: ToolbarConfig = {
|
|||||||
showTimeScale: true, // 保留时间刻度切换
|
showTimeScale: true, // 保留时间刻度切换
|
||||||
timeScaleDimensions: ['week', 'month'],
|
timeScaleDimensions: ['week', 'month'],
|
||||||
defaultTimeScale: 'month',
|
defaultTimeScale: 'month',
|
||||||
showExpandCollapse: false // 隐藏展开/折叠
|
showExpandCollapse: false, // 隐藏展开/折叠
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
> **💡 配置建议**:
|
> **💡 配置建议**:
|
||||||
|
>
|
||||||
> - **默认配置**:不传 `toolbar-config` 时,所有按钮默认显示
|
> - **默认配置**:不传 `toolbar-config` 时,所有按钮默认显示
|
||||||
> - **按需显示**:根据业务需求隐藏不需要的功能按钮
|
> - **按需显示**:根据业务需求隐藏不需要的功能按钮
|
||||||
> - **时间刻度**:`timeScaleDimensions` 控制显示哪些时间维度,建议选择 2-4 个常用维度
|
> - **时间刻度**:`timeScaleDimensions` 控制显示哪些时间维度,建议选择 2-4 个常用维度
|
||||||
@@ -1274,7 +1285,7 @@ const toolbarConfig: ToolbarConfig = {
|
|||||||
**类型定义:**
|
**类型定义:**
|
||||||
|
|
||||||
| 字段名 | 类型 | 默认值 | 说明 |
|
| 字段名 | 类型 | 默认值 | 说明 |
|
||||||
|--------|------|--------|------|
|
| ---------------- | ------------------------ | ------- | ------------------------------------------------------------------------------ |
|
||||||
| `columns` | `TaskListColumnConfig[]` | 默认8列 | 任务列表的列配置数组,定义显示哪些列及其属性 |
|
| `columns` | `TaskListColumnConfig[]` | 默认8列 | 任务列表的列配置数组,定义显示哪些列及其属性 |
|
||||||
| `showAllColumns` | `boolean` | `true` | 是否显示所有列。`true` 时忽略 `columns` 中的 `visible` 设置 |
|
| `showAllColumns` | `boolean` | `true` | 是否显示所有列。`true` 时忽略 `columns` 中的 `visible` 设置 |
|
||||||
| `defaultWidth` | `number \| string` | `320` | 默认展开宽度。支持像素数字(如 `320`)或百分比字符串(如 `'30%'`) |
|
| `defaultWidth` | `number \| string` | `320` | 默认展开宽度。支持像素数字(如 `320`)或百分比字符串(如 `'30%'`) |
|
||||||
@@ -1284,7 +1295,7 @@ const toolbarConfig: ToolbarConfig = {
|
|||||||
**TaskListColumnConfig 类型定义:**
|
**TaskListColumnConfig 类型定义:**
|
||||||
|
|
||||||
| 字段名 | 类型 | 必填 | 说明 |
|
| 字段名 | 类型 | 必填 | 说明 |
|
||||||
|--------|------|------|------|
|
| ---------- | --------- | ---- | ---------------------------------------------------------------- |
|
||||||
| `key` | `string` | ✅ | 列的唯一标识符,用于访问 Task 对象中的字段,也用于国际化 |
|
| `key` | `string` | ✅ | 列的唯一标识符,用于访问 Task 对象中的字段,也用于国际化 |
|
||||||
| `label` | `string` | - | 列的显示标签(表头文字) |
|
| `label` | `string` | - | 列的显示标签(表头文字) |
|
||||||
| `cssClass` | `string` | - | 自定义 CSS 类名 |
|
| `cssClass` | `string` | - | 自定义 CSS 类名 |
|
||||||
@@ -1295,10 +1306,7 @@ const toolbarConfig: ToolbarConfig = {
|
|||||||
|
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<GanttChart
|
<GanttChart :tasks="tasks" :task-list-config="taskListConfig" />
|
||||||
:tasks="tasks"
|
|
||||||
:task-list-config="taskListConfig"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -1318,10 +1326,7 @@ const taskListConfig: TaskListConfig = {
|
|||||||
|
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<GanttChart
|
<GanttChart :tasks="tasks" :task-list-config="taskListConfig" />
|
||||||
:tasks="tasks"
|
|
||||||
:task-list-config="taskListConfig"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -1343,10 +1348,7 @@ const taskListConfig: TaskListConfig = {
|
|||||||
|
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<GanttChart
|
<GanttChart :tasks="tasks" :task-list-config="taskListConfig" />
|
||||||
:tasks="tasks"
|
|
||||||
:task-list-config="taskListConfig"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -1431,10 +1433,7 @@ const taskListConfig: TaskListConfig = {
|
|||||||
|
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<GanttChart
|
<GanttChart :tasks="tasks" :task-list-config="taskListConfig" />
|
||||||
:tasks="tasks"
|
|
||||||
:task-list-config="taskListConfig"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -1473,6 +1472,7 @@ const taskListConfig = computed<TaskListConfig>(() => ({
|
|||||||
```
|
```
|
||||||
|
|
||||||
> **💡 配置说明**:
|
> **💡 配置说明**:
|
||||||
|
>
|
||||||
> - **默认行为**:不传 `task-list-config` 时,显示所有 8 个默认列,宽度为 320px
|
> - **默认行为**:不传 `task-list-config` 时,显示所有 8 个默认列,宽度为 320px
|
||||||
> - **宽度单位**:支持像素(`number`)和百分比(`string`,如 `'30%'`)两种方式
|
> - **宽度单位**:支持像素(`number`)和百分比(`string`,如 `'30%'`)两种方式
|
||||||
> - **百分比计算**:基于甘特图容器的总宽度,响应式调整
|
> - **百分比计算**:基于甘特图容器的总宽度,响应式调整
|
||||||
@@ -1489,7 +1489,7 @@ const taskListConfig = computed<TaskListConfig>(() => ({
|
|||||||
**配置字段:**
|
**配置字段:**
|
||||||
|
|
||||||
| 字段名 | 类型 | 默认值 | 说明 |
|
| 字段名 | 类型 | 默认值 | 说明 |
|
||||||
|--------|------|--------|------|
|
| ------------------- | --------- | ------- | ------------------------------- |
|
||||||
| `showAvatar` | `boolean` | `true` | 是否展示头像 |
|
| `showAvatar` | `boolean` | `true` | 是否展示头像 |
|
||||||
| `showTitle` | `boolean` | `true` | 是否展示标题文字 |
|
| `showTitle` | `boolean` | `true` | 是否展示标题文字 |
|
||||||
| `showProgress` | `boolean` | `true` | 是否展示进度文字 |
|
| `showProgress` | `boolean` | `true` | 是否展示进度文字 |
|
||||||
@@ -1499,6 +1499,7 @@ const taskListConfig = computed<TaskListConfig>(() => ({
|
|||||||
| `dragDelayTime` | `number` | `150` | 拖拽延迟时间(毫秒) |
|
| `dragDelayTime` | `number` | `150` | 拖拽延迟时间(毫秒) |
|
||||||
|
|
||||||
> **💡 编辑权限控制**:
|
> **💡 编辑权限控制**:
|
||||||
|
>
|
||||||
> - **全局控制**:使用 `<GanttChart :allow-drag-and-resize="false" />` 禁用所有任务的拖拽/拉伸
|
> - **全局控制**:使用 `<GanttChart :allow-drag-and-resize="false" />` 禁用所有任务的拖拽/拉伸
|
||||||
> - **单个任务控制**:设置任务对象的 `isEditable: false` 属性单独控制某个任务
|
> - **单个任务控制**:设置任务对象的 `isEditable: false` 属性单独控制某个任务
|
||||||
|
|
||||||
@@ -1506,10 +1507,7 @@ const taskListConfig = computed<TaskListConfig>(() => ({
|
|||||||
|
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<GanttChart
|
<GanttChart :tasks="tasks" :task-bar-config="taskBarConfig" />
|
||||||
:tasks="tasks"
|
|
||||||
:task-bar-config="taskBarConfig"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -1535,10 +1533,7 @@ const taskBarConfig: TaskBarConfig = {
|
|||||||
|
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<GanttChart
|
<GanttChart :tasks="tasks" :allow-drag-and-resize="false" />
|
||||||
:tasks="tasks"
|
|
||||||
:allow-drag-and-resize="false"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -1612,6 +1607,7 @@ const taskBarConfig = computed<TaskBarConfig>(() => ({
|
|||||||
**核心设计思路:**
|
**核心设计思路:**
|
||||||
|
|
||||||
1. **基础缓冲机制**:在任务的实际时间范围基础上,根据不同视图添加固定的缓冲区
|
1. **基础缓冲机制**:在任务的实际时间范围基础上,根据不同视图添加固定的缓冲区
|
||||||
|
|
||||||
- 小时视图:任务范围前后各 ±1 天
|
- 小时视图:任务范围前后各 ±1 天
|
||||||
- 日视图:任务范围前后各 ±30 天
|
- 日视图:任务范围前后各 ±30 天
|
||||||
- 周视图:任务范围前后各 ±8 周(约2个月)
|
- 周视图:任务范围前后各 ±8 周(约2个月)
|
||||||
@@ -1620,10 +1616,12 @@ const taskBarConfig = computed<TaskBarConfig>(() => ({
|
|||||||
- 年视图:任务范围前后各 ±1 年
|
- 年视图:任务范围前后各 ±1 年
|
||||||
|
|
||||||
2. **容器宽度适配**:基础缓冲后,如果计算出的时间线宽度小于容器宽度,会自动扩展范围
|
2. **容器宽度适配**:基础缓冲后,如果计算出的时间线宽度小于容器宽度,会自动扩展范围
|
||||||
|
|
||||||
- 计算容器需要的时间单位数(天/周/月/季度/年)
|
- 计算容器需要的时间单位数(天/周/月/季度/年)
|
||||||
- 在基础范围两侧**对称扩展**,确保时间线填充满容器
|
- 在基础范围两侧**对称扩展**,确保时间线填充满容器
|
||||||
|
|
||||||
3. **空数据处理**:当没有任务数据时,根据容器宽度和时间刻度计算合理的时间范围
|
3. **空数据处理**:当没有任务数据时,根据容器宽度和时间刻度计算合理的时间范围
|
||||||
|
|
||||||
- 以当前日期为中心
|
- 以当前日期为中心
|
||||||
- 根据容器宽度动态计算需要显示的时间跨度
|
- 根据容器宽度动态计算需要显示的时间跨度
|
||||||
- 确保最小显示范围(如日视图至少60天,周视图至少20周等)
|
- 确保最小显示范围(如日视图至少60天,周视图至少20周等)
|
||||||
@@ -1635,7 +1633,7 @@ const taskBarConfig = computed<TaskBarConfig>(() => ({
|
|||||||
**各视图计算模式对照表:**
|
**各视图计算模式对照表:**
|
||||||
|
|
||||||
| 视图 | 单位宽度 | 基础缓冲 | 空数据最小范围 | 容器自动填充? |
|
| 视图 | 单位宽度 | 基础缓冲 | 空数据最小范围 | 容器自动填充? |
|
||||||
|------|----------|----------|----------------|----------|
|
| -------- | -------------------- | -------- | -------------- | -------------- |
|
||||||
| 小时视图 | 30px/时 | ±1天 | 3天 | ✅ |
|
| 小时视图 | 30px/时 | ±1天 | 3天 | ✅ |
|
||||||
| 日视图 | 30px/天 | ±30天 | 60天 | ✅ |
|
| 日视图 | 30px/天 | ±30天 | 60天 | ✅ |
|
||||||
| 周视图 | 60px/周 | ±2月 | 20周 | ✅ |
|
| 周视图 | 60px/周 | ±2月 | 20周 | ✅ |
|
||||||
@@ -1646,11 +1644,13 @@ const taskBarConfig = computed<TaskBarConfig>(() => ({
|
|||||||
**实际应用场景:**
|
**实际应用场景:**
|
||||||
|
|
||||||
- **短期任务**(如1周项目, 分辨率1080):
|
- **短期任务**(如1周项目, 分辨率1080):
|
||||||
|
|
||||||
- 不会导致时间线过窄,自动扩展到填充满容器
|
- 不会导致时间线过窄,自动扩展到填充满容器
|
||||||
- 日视图:1周(7天×30px=210px) → 扩展至 ≥1200px(约40天)
|
- 日视图:1周(7天×30px=210px) → 扩展至 ≥1200px(约40天)
|
||||||
- 周视图:1周(60px) → 扩展至 ≥1200px(约20周)
|
- 周视图:1周(60px) → 扩展至 ≥1200px(约20周)
|
||||||
|
|
||||||
- **长期项目**(如2年项目):
|
- **长期项目**(如2年项目):
|
||||||
|
|
||||||
- 添加固定缓冲后,自动适配容器
|
- 添加固定缓冲后,自动适配容器
|
||||||
- 月视图:24个月 + 缓冲 → 如需要则扩展至容器宽度
|
- 月视图:24个月 + 缓冲 → 如需要则扩展至容器宽度
|
||||||
- 季度视图:8个季度 + 缓冲 → 如需要则扩展至容器宽度
|
- 季度视图:8个季度 + 缓冲 → 如需要则扩展至容器宽度
|
||||||
@@ -1662,6 +1662,7 @@ const taskBarConfig = computed<TaskBarConfig>(() => ({
|
|||||||
- 季度/年视图:显示至少5年
|
- 季度/年视图:显示至少5年
|
||||||
|
|
||||||
> **💡 自动化优势**:
|
> **💡 自动化优势**:
|
||||||
|
>
|
||||||
> - 无需手动设置 `startDate` 和 `endDate`,组件会自动计算最优范围
|
> - 无需手动设置 `startDate` 和 `endDate`,组件会自动计算最优范围
|
||||||
> - 响应式容器宽度变化,时间线自动重新计算
|
> - 响应式容器宽度变化,时间线自动重新计算
|
||||||
> - 不同视图独立优化,切换视图时自动调整到最佳显示效果
|
> - 不同视图独立优化,切换视图时自动调整到最佳显示效果
|
||||||
@@ -1676,10 +1677,7 @@ const taskBarConfig = computed<TaskBarConfig>(() => ({
|
|||||||
|
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<GanttChart
|
<GanttChart :tasks="tasks" :on-theme-change="handleThemeChange" />
|
||||||
:tasks="tasks"
|
|
||||||
:on-theme-change="handleThemeChange"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -1748,10 +1746,7 @@ const handleThemeChange = (isDark: boolean) => {
|
|||||||
|
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<GanttChart
|
<GanttChart :tasks="tasks" :on-language-change="handleLanguageChange" />
|
||||||
:tasks="tasks"
|
|
||||||
:on-language-change="handleLanguageChange"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -1769,10 +1764,7 @@ const handleLanguageChange = (lang: 'zh-CN' | 'en-US') => {
|
|||||||
|
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<GanttChart
|
<GanttChart :tasks="tasks" :locale-messages="customMessages" />
|
||||||
:tasks="tasks"
|
|
||||||
:locale-messages="customMessages"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -1829,6 +1821,7 @@ const customMessages = {
|
|||||||
```
|
```
|
||||||
|
|
||||||
> **💡 提示**:
|
> **💡 提示**:
|
||||||
|
>
|
||||||
> - `localeMessages` 采用**深度合并**策略,只需传递需要覆盖的字段即可
|
> - `localeMessages` 采用**深度合并**策略,只需传递需要覆盖的字段即可
|
||||||
> - 支持嵌套对象,如 `taskList.name`、`toolbar.addTask` 等
|
> - 支持嵌套对象,如 `taskList.name`、`toolbar.addTask` 等
|
||||||
> - 完整的翻译键请参考组件内置的 `messages['zh-CN']` 对象
|
> - 完整的翻译键请参考组件内置的 `messages['zh-CN']` 对象
|
||||||
@@ -1846,14 +1839,14 @@ const customMessages = {
|
|||||||
**插槽参数:**
|
**插槽参数:**
|
||||||
|
|
||||||
| 参数名 | 类型 | 来源 | 说明 |
|
| 参数名 | 类型 | 来源 | 说明 |
|
||||||
|--------|------|------|------|
|
| ------ | ---------------------------- | ---- | ---------------- |
|
||||||
| `type` | `'task-row'` \| `'task-bar'` | 通用 | 插槽调用位置标识 |
|
| `type` | `'task-row'` \| `'task-bar'` | 通用 | 插槽调用位置标识 |
|
||||||
| `task` | `Task` | 通用 | 当前任务对象 |
|
| `task` | `Task` | 通用 | 当前任务对象 |
|
||||||
|
|
||||||
**TaskRow 特有参数(当 `type === 'task-row'` 时):**
|
**TaskRow 特有参数(当 `type === 'task-row'` 时):**
|
||||||
|
|
||||||
| 参数名 | 类型 | 说明 |
|
| 参数名 | 类型 | 说明 |
|
||||||
|--------|------|------|
|
| ---------------- | -------------------------------- | ---------------- |
|
||||||
| `isRowContent` | `boolean` | 标识为行内容 |
|
| `isRowContent` | `boolean` | 标识为行内容 |
|
||||||
| `level` | `number` | 任务层级 |
|
| `level` | `number` | 任务层级 |
|
||||||
| `indent` | `string` | 缩进样式 |
|
| `indent` | `string` | 缩进样式 |
|
||||||
@@ -1875,7 +1868,7 @@ const customMessages = {
|
|||||||
**TaskBar 特有参数(当 `type === 'task-bar'` 时):**
|
**TaskBar 特有参数(当 `type === 'task-bar'` 时):**
|
||||||
|
|
||||||
| 参数名 | 类型 | 说明 |
|
| 参数名 | 类型 | 说明 |
|
||||||
|--------|------|------|
|
| ------------------ | --------------- | ---------------------------------------------------------------------------------- |
|
||||||
| `status` | `object` | 任务状态对象,包含 `type`, `color`, `bgColor`, `borderColor` |
|
| `status` | `object` | 任务状态对象,包含 `type`, `color`, `bgColor`, `borderColor` |
|
||||||
| `statusType` | `string` | 状态类型:`'completed'`, `'delayed'`, `'in-progress'`, `'not-started'`, `'parent'` |
|
| `statusType` | `string` | 状态类型:`'completed'`, `'delayed'`, `'in-progress'`, `'not-started'`, `'parent'` |
|
||||||
| `isParent` | `boolean` | 是否为父任务 |
|
| `isParent` | `boolean` | 是否为父任务 |
|
||||||
@@ -1891,11 +1884,7 @@ const customMessages = {
|
|||||||
<GanttChart :tasks="tasks">
|
<GanttChart :tasks="tasks">
|
||||||
<template #custom-task-content="slotProps">
|
<template #custom-task-content="slotProps">
|
||||||
<!-- 根据类型渲染不同内容 -->
|
<!-- 根据类型渲染不同内容 -->
|
||||||
<CustomTaskContent
|
<CustomTaskContent :task="slotProps.task" :type="slotProps.type" :status="slotProps.status" />
|
||||||
:task="slotProps.task"
|
|
||||||
:type="slotProps.type"
|
|
||||||
:status="slotProps.status"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</GanttChart>
|
</GanttChart>
|
||||||
</template>
|
</template>
|
||||||
@@ -1913,8 +1902,8 @@ const tasks = ref<Task[]>([
|
|||||||
name: '<strong>重要任务</strong>',
|
name: '<strong>重要任务</strong>',
|
||||||
startDate: '2025-01-01',
|
startDate: '2025-01-01',
|
||||||
endDate: '2025-01-10',
|
endDate: '2025-01-10',
|
||||||
progress: 50
|
progress: 50,
|
||||||
}
|
},
|
||||||
])
|
])
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
@@ -1991,6 +1980,7 @@ const props = defineProps<Props>()
|
|||||||
```
|
```
|
||||||
|
|
||||||
> **💡 使用场景**:
|
> **💡 使用场景**:
|
||||||
|
>
|
||||||
> - 支持 HTML 格式的任务名称
|
> - 支持 HTML 格式的任务名称
|
||||||
> - 添加自定义图标、标签或徽章
|
> - 添加自定义图标、标签或徽章
|
||||||
> - 根据任务状态显示不同样式
|
> - 根据任务状态显示不同样式
|
||||||
@@ -1998,6 +1988,7 @@ const props = defineProps<Props>()
|
|||||||
> - 显示额外的业务信息
|
> - 显示额外的业务信息
|
||||||
|
|
||||||
> **⚠️ 注意事项**:
|
> **⚠️ 注意事项**:
|
||||||
|
>
|
||||||
> - 插槽内容会同时在 TaskRow 和 TaskBar 中渲染
|
> - 插槽内容会同时在 TaskRow 和 TaskBar 中渲染
|
||||||
> - 需要根据 `type` 参数区分渲染位置
|
> - 需要根据 `type` 参数区分渲染位置
|
||||||
> - TaskRow 和 TaskBar 的可用空间不同,需要适配布局
|
> - TaskRow 和 TaskBar 的可用空间不同,需要适配布局
|
||||||
|
|||||||
Reference in New Issue
Block a user