@lee576/vue3-gantt 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -21,37 +21,78 @@
21
21
 
22
22
  ## 界面预览
23
23
 
24
- <img width="1913" height="923" alt="image" src="https://github.com/user-attachments/assets/34562bf8-0709-44aa-a05d-6e970ea8b57f" />
25
- <img width="1915" height="916" alt="image" src="https://github.com/user-attachments/assets/d6a60ba1-9f5b-479a-b402-68014ec7c935" />
24
+ <div align="center">
25
+ <img src="https://github.com/user-attachments/assets/34562bf8-0709-44aa-a05d-6e970ea8b57f" alt="Vue3 Gantt Chart - Light Theme" />
26
+ <p><em>浅色主题 - 完整的任务管理界面</em></p>
27
+
28
+ <img src="https://github.com/user-attachments/assets/d6a60ba1-9f5b-479a-b402-68014ec7c935" alt="Vue3 Gantt Chart - Dark Theme" />
29
+ <p><em>深色主题 - 护眼模式</em></p>
30
+ </div>
26
31
 
27
32
  ```
28
33
 
29
- **主要特点:**
30
- - 🎯 左侧任务列表 + 右侧甘特图时间轴
31
- - 📊 可视化进度条显示任务完成度
32
- - 🔗 任务间依赖关系连线
33
- - 🎨 多主题支持(浅色/深色/彩色等)
34
- - 🖱️ 拖拽调整任务时间和进度
35
- - 🌍 多语言支持(中文/English/日本語/한국어/Français/Deutsch/Español/Русский)
36
-
37
- ## 特性
38
-
39
- - **多视图模式** - 支持月、日、周、时四种时间粒度视图
40
- - **任务依赖关系** - 支持 FS、SS、FF、SF 四种依赖类型
41
- - **里程碑功能** - 菱形图标标记项目关键节点,支持作为依赖源和目标
42
- - **主题系统** - 内置 5 种主题,支持自定义主题
43
- - **国际化支持** - 内置 8 种语言,可扩展更多语言
44
- - **进度管理** - 可视化进度条,支持拖拽调整进度
45
- - **交互操作** - 支持任务拖拽、调整大小、父子任务联动
46
- - **响应式设计** - 可调整分割面板比例
47
- - **高性能** - 虚拟滚动优化,支持大量任务数据
48
-
49
- ## 安装
34
+ **核心亮点:**
35
+ - 🎯 **双栏布局** - 左侧任务列表 + 右侧甘特图时间轴,信息一目了然
36
+ - 📊 **可视化进度** - 实时进度条显示,支持拖拽调整完成度
37
+ - 🔗 **智能依赖** - 四种依赖类型(FS/SS/FF/SF),自动绘制连线
38
+ - 🎨 **多主题切换** - 5种内置主题,支持深色模式和自定义主题
39
+ - 🖱️ **交互丰富** - 拖拽移动、调整大小、父子任务联动
40
+ - 🌍 **国际化** - 内置8种语言,轻松扩展更多语言
41
+ - ⚡ **高性能** - 虚拟滚动优化,轻松处理大量任务数据
42
+ - 💎 **里程碑** - 菱形标记关键节点,支持依赖关系
43
+
44
+ ## 核心特性
45
+
46
+ ### 📅 多视图模式
47
+ 支持四种时间粒度,满足不同场景需求:
48
+ - **月视图** - 长期项目规划,按天显示
49
+ - **周视图** - 中期项目跟踪,按周显示
50
+ - **日视图** - 短期任务管理,精确到天
51
+ - **时视图** - 精细任务调度,按小时显示
52
+
53
+ ### 🔗 任务依赖管理
54
+ - **完成-开始 (FS)** - 前置任务完成后,后续任务才能开始
55
+ - **开始-开始 (SS)** - 两个任务同时开始
56
+ - **完成-完成 (FF)** - 两个任务同时完成
57
+ - **开始-完成 (SF)** - 后续任务开始后,前置任务才能完成
58
+
59
+ ### 💎 里程碑功能
60
+ - 菱形图标标记项目关键节点
61
+ - 支持作为依赖关系的源和目标
62
+ - 自动识别(开始时间=结束时间)或手动标记
63
+
64
+ ### 🎨 主题系统
65
+ - 内置 5 种精美主题(Metro/Dark/Modern/Classic/Colorful)
66
+ - 支持深色模式,护眼舒适
67
+ - 完整的 CSS 变量支持,轻松自定义主题
68
+ - 主题设置自动保存到浏览器
69
+
70
+ ### 🌍 国际化支持
71
+ - 内置 8 种语言(中/英/日/韩/法/德/西/俄)
72
+ - 即时切换,无需刷新页面
73
+ - 所有界面元素完整翻译
74
+ - 时间轴表头自动本地化
75
+ - 易于扩展新语言
76
+
77
+ ### 🖱️ 交互操作
78
+ - **拖拽移动** - 修改任务开始和结束日期
79
+ - **调整大小** - 拖拽边缘调整任务时长
80
+ - **进度调整** - 拖拽三角滑块调整完成度
81
+ - **父子联动** - 父任务移动时子任务自动跟随
82
+ - **分割面板** - 可调整左右区域比例
83
+
84
+ ### ⚡ 性能优化
85
+ - 虚拟滚动渲染,支持海量任务数据
86
+ - 节流更新机制,避免频繁重绘
87
+ - 计算结果缓存,提升响应速度
88
+ - 按需渲染连线,优化绘制性能
89
+
90
+ ## 🚀 安装使用
50
91
 
51
92
  ### 方式一:通过 npm 安装(推荐)
52
93
 
53
94
  ```bash
54
- # 使用 npm 安装
95
+ # 使用 npm
55
96
  npm install @lee576/vue3-gantt
56
97
 
57
98
  # 或使用 yarn
@@ -64,8 +105,9 @@ pnpm add @lee576/vue3-gantt
64
105
  ### 方式二:从源码构建
65
106
 
66
107
  ```bash
67
- # 克隆项目
108
+ # 克隆仓库
68
109
  git clone https://github.com/lee576/vue3-gantt.git
110
+ cd vue3-gantt
69
111
 
70
112
  # 安装依赖
71
113
  npm install
@@ -74,151 +116,118 @@ npm install
74
116
  npm run dev
75
117
  ```
76
118
 
77
- ## 依赖项
119
+ ## 📚 快速开始
120
+
121
+ ### 1️⃣ 引入组件
78
122
 
79
- - @vueuse/core ^13.0.0
80
- - dayjs ^1.11.13
81
- - interactjs ^1.10.27
82
- - svg.js ^2.7.1
83
- - vue ^3.5.13
84
- - zod ^3.24.2
123
+ ```typescript
124
+ import { createApp } from 'vue';
125
+ import Gantt from '@lee576/vue3-gantt';
126
+ import '@lee576/vue3-gantt/style.css';
85
127
 
86
- ## 基本使用
128
+ const app = createApp(App);
129
+ app.use(Gantt); // 全局注册
130
+ ```
87
131
 
88
- ### 1. 引入组件和样式
132
+ 或在组件中单独引入:
89
133
 
90
- ```typescript
91
- import { ref, onMounted } from 'vue';
92
- import dayjs from 'dayjs';
93
- // 引入甘特图组件和类型
134
+ ```vue
135
+ <script setup lang="ts">
136
+ import { ref } from 'vue';
94
137
  import Gantt, {
95
138
  type DataConfig,
96
139
  type StyleConfig,
97
- type EventConfig
140
+ type EventConfig,
141
+ LinkType
98
142
  } from '@lee576/vue3-gantt';
99
- // 引入样式文件
100
143
  import '@lee576/vue3-gantt/style.css';
101
- import { LinkType } from '@lee576/vue3-gantt';
144
+ </script>
102
145
  ```
103
146
 
104
- ### 2. 配置容器高度(重要!)
147
+ ### 2️⃣ 配置容器高度(重要!)
105
148
 
106
- **组件必须有明确的容器高度才能正常显示**。以下是几种推荐的配置方式:
149
+ > ⚠️ **注意**:组件**必须有明确的容器高度**才能正常显示。
107
150
 
108
- #### 方式 1:使用视口高度(最简单)
151
+ **推荐方法(任选其一):**
109
152
 
110
153
  ```vue
154
+ <!-- 方法1:使用视口高度(最简单) -->
111
155
  <template>
112
- <div class="gantt-container">
113
- <gantt
114
- :styleConfig="styleConfig"
115
- :dataConfig="dataConfig"
116
- :eventConfig="eventConfig"
117
- />
156
+ <div style="height: 100vh;">
157
+ <gantt :dataConfig="dataConfig" :styleConfig="styleConfig" />
118
158
  </div>
119
159
  </template>
120
160
 
121
- <style scoped>
122
- .gantt-container {
123
- height: 100vh; /* 直接使用视口高度 */
124
- }
125
- </style>
126
- ```
127
-
128
- #### 方式 2:使用百分比高度(需要配置 html/body)
129
-
130
- ```vue
161
+ <!-- 方法2:使用固定高度 -->
131
162
  <template>
132
- <div id="app">
133
- <gantt
134
- :styleConfig="styleConfig"
135
- :dataConfig="dataConfig"
136
- :eventConfig="eventConfig"
137
- />
163
+ <div style="height: 800px;">
164
+ <gantt :dataConfig="dataConfig" :styleConfig="styleConfig" />
138
165
  </div>
139
166
  </template>
140
167
 
141
- <style>
142
- /* 全局样式:确保 html 和 body 有高度 */
143
- html, body {
144
- height: 100%;
145
- margin: 0;
146
- padding: 0;
147
- }
148
-
149
- #app {
150
- height: 100%; /* 现在 100% 就能正常工作了 */
151
- }
152
- </style>
153
- ```
154
-
155
- #### 方式 3:使用固定像素值
156
-
157
- ```vue
158
- <style scoped>
159
- .gantt-container {
160
- height: 800px; /* 固定高度 */
161
- }
162
- </style>
163
- ```
164
-
165
- #### 方式 4:使用 Flex 布局
166
-
167
- ```vue
168
+ <!-- 方法3:Flex 布局 -->
168
169
  <template>
169
- <div class="page-wrapper">
170
- <div class="header">Header</div>
171
- <div class="gantt-container">
172
- <gantt ... />
170
+ <div style="display: flex; flex-direction: column; height: 100vh;">
171
+ <div>Header</div>
172
+ <div style="flex: 1;"> <!-- 自动填充剩余空间 -->
173
+ <gantt :dataConfig="dataConfig" :styleConfig="styleConfig" />
173
174
  </div>
174
175
  </div>
175
176
  </template>
177
+ ```
176
178
 
177
- <style scoped>
178
- .page-wrapper {
179
- display: flex;
180
- flex-direction: column;
181
- height: 100vh;
182
- }
179
+ <details>
180
+ <summary>💡 为什么需要设置高度?</summary>
183
181
 
184
- .gantt-container {
185
- flex: 1; /* 自动填充剩余空间 */
186
- }
187
- </style>
188
- ```
182
+ 组件内部使用了 `height: 100%`,根据 CSS 规范,百分比高度需要父元素有明确的高度才能计算。如果父容器没有设置高度,组件会高度坑塌。
189
183
 
190
- ### 3. 配置组件
184
+ **解决方案**:
185
+ - 使用 `100vh`(视口高度)
186
+ - 使用固定像素值(如 `800px`)
187
+ - 使用 Flex 布局的 `flex: 1`
188
+ - 配置 `html, body { height: 100%; }` 后使用 `100%`
189
+
190
+ </details>
191
+
192
+ ### 3️⃣ 基本配置
191
193
 
192
194
  ```vue
193
195
  <template>
194
- <gantt
195
- :styleConfig="styleConfig"
196
- :dataConfig="dataConfig"
197
- :eventConfig="eventConfig"
198
- />
196
+ <div style="height: 100vh;">
197
+ <gantt
198
+ :dataConfig="dataConfig"
199
+ :styleConfig="styleConfig"
200
+ :eventConfig="eventConfig"
201
+ />
202
+ </div>
199
203
  </template>
200
- ```
201
204
 
202
- ```typescript
203
- // 样式配置
205
+ <script setup lang="ts">
206
+ import { ref, onMounted } from 'vue';
207
+ import dayjs from 'dayjs';
208
+ import Gantt, {
209
+ type DataConfig,
210
+ type StyleConfig,
211
+ type EventConfig,
212
+ LinkType
213
+ } from '@lee576/vue3-gantt';
214
+ import '@lee576/vue3-gantt/style.css';
215
+
216
+ // 🎨 样式配置
204
217
  const styleConfig = ref<StyleConfig>({
205
218
  headersHeight: 100, // 表头高度
206
219
  rowHeight: 60, // 行高
207
220
  setBarColor: (row) => {
208
221
  // 自定义任务条颜色
209
- const colorMap = {
210
- '紧急': 'red',
211
- '重要': 'blue',
212
- '一般': 'gray'
213
- };
214
- return colorMap[row.level] ?? 'black';
222
+ const colorMap = { '紧急': '#ef4444', '重要': '#3b82f6', '一般': '#6b7280' };
223
+ return colorMap[row.level] ?? '#000';
215
224
  }
216
225
  });
217
226
 
218
- // 数据配置
227
+ // 📊 数据配置
219
228
  const dataConfig = ref<DataConfig>({
220
- queryStartDate: '',
221
- queryEndDate: '',
229
+ queryStartDate: dayjs().startOf('month').format('YYYY-MM-DD'),
230
+ queryEndDate: dayjs().endOf('month').format('YYYY-MM-DD'),
222
231
  dataSource: [],
223
232
  dependencies: [],
224
233
  mapFields: {
@@ -233,40 +242,35 @@ const dataConfig = ref<DataConfig>({
233
242
  },
234
243
  taskHeaders: [
235
244
  { title: '序号', width: 80, property: 'no', show: true },
236
- { title: '任务名称', width: 190, property: 'task', show: true },
245
+ { title: '任务名称', width: 200, property: 'task', show: true },
237
246
  { title: '优先级', width: 90, property: 'priority', show: true },
238
247
  { title: '开始时间', width: 150, property: 'startdate', show: true },
239
248
  { title: '结束时间', width: 150, property: 'enddate', show: true },
240
- { title: '耗时', width: 90, property: 'takestime', show: true }
241
249
  ]
242
250
  });
243
251
 
244
- // 事件配置
252
+ // 事件配置
245
253
  const eventConfig = ref<EventConfig>({
246
- addRootTask: (row) => console.log('添加根任务', row),
247
- addSubTask: (task) => console.log('添加子任务', task),
248
- removeTask: (task) => console.log('删除任务', task),
249
- editTask: (task) => console.log('编辑任务', task),
250
254
  queryTask: async (startDate, endDate, mode) => {
251
255
  // 查询任务数据
252
- dataConfig.value.dataSource = await fetchTasks(startDate, endDate);
256
+ const tasks = await fetchTasks(startDate, endDate);
257
+ dataConfig.value.dataSource = tasks;
253
258
  },
254
259
  barDate: (id, startDate, endDate) => {
255
- console.log('任务日期变更', id, startDate, endDate);
256
- },
257
- allowChangeTaskDate: (allow) => {
258
- console.log('允许修改日期', allow);
260
+ console.log('任务日期变更', { id, startDate, endDate });
259
261
  },
260
262
  updateProgress: (detail) => {
261
263
  console.log('进度更新', detail);
262
264
  }
263
265
  });
264
266
 
267
+ // 初始化加载数据
265
268
  onMounted(() => {
266
- const startDate = dayjs().startOf('month').format('YYYY-MM-DD');
267
- const endDate = dayjs().endOf('month').format('YYYY-MM-DD');
268
- eventConfig.value.queryTask(startDate, endDate, '月');
269
+ const start = dayjs().startOf('month').format('YYYY-MM-DD');
270
+ const end = dayjs().endOf('month').format('YYYY-MM-DD');
271
+ eventConfig.value.queryTask?.(start, end, '月');
269
272
  });
273
+ </script>
270
274
  ```
271
275
 
272
276
  ## 配置详解