diff --git a/npm-demo/src/components/GanttTest.vue b/npm-demo/src/components/GanttTest.vue
index e92bb37..5d6dc1a 100644
--- a/npm-demo/src/components/GanttTest.vue
+++ b/npm-demo/src/components/GanttTest.vue
@@ -251,8 +251,8 @@ const onTaskAdded = (res) => {
@@ -400,23 +400,23 @@ const onTaskAdded = (res) => {
transition: all 0.3s;
}
-.btn-primary {
+.gantt-btn-primary {
background: #409eff;
color: white;
border-color: #409eff;
}
-.btn-primary:hover {
+.gantt-btn-primary:hover {
background: #66b1ff;
border-color: #66b1ff;
}
-.btn-default {
+.gantt-btn-default {
background: white;
color: #606266;
}
-.btn-default:hover {
+.gantt-btn-default:hover {
color: #409eff;
border-color: #409eff;
}
diff --git a/npm-webpack-demo/src/App.vue b/npm-webpack-demo/src/App.vue
index ec08be0..1e226b4 100644
--- a/npm-webpack-demo/src/App.vue
+++ b/npm-webpack-demo/src/App.vue
@@ -24,8 +24,8 @@
-
-
+
+
@@ -54,8 +54,8 @@
@@ -409,23 +409,23 @@ const onTaskAdded = (res) => {
transition: all 0.3s;
}
-.btn-primary {
+.gantt-btn-primary {
background: #409eff;
color: white;
border-color: #409eff;
}
-.btn-primary:hover {
+.gantt-btn-primary:hover {
background: #66b1ff;
border-color: #66b1ff;
}
-.btn-default {
+.gantt-btn-default {
background: white;
color: #606266;
}
-.btn-default:hover {
+.gantt-btn-default:hover {
color: #409eff;
border-color: #409eff;
}
diff --git a/package.json b/package.json
index cee9db7..e2895b9 100644
--- a/package.json
+++ b/package.json
@@ -2,11 +2,22 @@
"name": "jordium-gantt-vue3",
"version": "1.4.6-patch.1",
"type": "module",
- "main": "dist/jordium-gantt-vue3.cjs.js",
- "module": "dist/jordium-gantt-vue3.es.js",
- "types": "dist/jordium-gantt-vue3.d.ts",
+ "main": "npm-package/dist/jordium-gantt-vue3.cjs.js",
+ "module": "npm-package/dist/jordium-gantt-vue3.es.js",
+ "types": "npm-package/dist/index.d.ts",
+ "exports": {
+ ".": {
+ "types": "./npm-package/dist/index.d.ts",
+ "require": "./npm-package/dist/jordium-gantt-vue3.cjs.js",
+ "import": "./npm-package/dist/jordium-gantt-vue3.es.js"
+ },
+ "./styles": "./npm-package/dist/jordium-gantt-vue3-styles.js",
+ "./styles.js": "./npm-package/dist/jordium-gantt-vue3-styles.js",
+ "./index.css": "./npm-package/dist/assets/jordium-gantt-vue3.css",
+ "./npm-package/*": "./npm-package/*"
+ },
"files": [
- "dist"
+ "npm-package"
],
"license": "MIT",
"repository": {
diff --git a/scripts/generate-css-export.js b/scripts/generate-css-export.js
index 73ec745..2cb698f 100644
--- a/scripts/generate-css-export.js
+++ b/scripts/generate-css-export.js
@@ -9,7 +9,7 @@ const __dirname = path.dirname(__filename)
// 构建后生成CSS导出文件
function generateCssExport() {
- const distDir = path.resolve(__dirname, '../../npm-package/dist')
+ const distDir = path.resolve(__dirname, '../npm-package/dist')
const assetsDir = path.join(distDir, 'assets')
const expectedCssFile = path.join(assetsDir, 'jordium-gantt-vue3.css')
const outputFile = path.join(distDir, 'jordium-gantt-vue3-styles.js')
diff --git a/src/components/ConfirmTimerDialog.vue b/src/components/ConfirmTimerDialog.vue
index 7bd4785..8f3a64e 100644
--- a/src/components/ConfirmTimerDialog.vue
+++ b/src/components/ConfirmTimerDialog.vue
@@ -46,8 +46,8 @@ const messageTaskName = computed(() => {
rows="3"
>
-
-
+
+
@@ -108,7 +108,7 @@ const messageTaskName = computed(() => {
gap: 12px;
margin-top: 8px;
}
-.btn {
+.gantt-btn {
min-width: 96px;
padding: 10px 0;
border: none;
@@ -122,11 +122,11 @@ const messageTaskName = computed(() => {
align-items: center;
justify-content: center;
}
-.btn-confirm {
+.gantt-btn-confirm {
background: #4caf50;
color: #fff;
}
-.btn-confirm:hover {
+.gantt-btn-confirm:hover {
background: #43a047;
}
diff --git a/src/components/GanttChart.vue b/src/components/GanttChart.vue
index e922c75..264eb7b 100644
--- a/src/components/GanttChart.vue
+++ b/src/components/GanttChart.vue
@@ -65,6 +65,8 @@ const emit = defineEmits([
'task-deleted',
'task-added',
'task-updated',
+ 'task-collapse-change', // 任务折叠状态变化事件
+ 'link-deleted', // 链接删除事件
// 工具栏事件
'add-task',
'add-milestone',
@@ -72,6 +74,9 @@ const emit = defineEmits([
'milestone-saved',
'milestone-deleted',
'milestone-icon-changed',
+ // 任务关系事件
+ 'add-predecessor',
+ 'add-successor',
// TaskRow拖拽事件
'task-row-moved',
])
@@ -584,6 +589,9 @@ const handleTaskCollapseChange = (task: Task) => {
// 触发Timeline重新计算
updateTaskTrigger.value++
+
+ // 向外发出折叠状态变化事件
+ emit('task-collapse-change', task)
}
// 全部展开任务
@@ -744,6 +752,11 @@ const expandTaskListText = computed(() => t.value.expandTaskList)
// 为TaskList提供层级数据(保持原始层级结构,只扁平化里程碑)
const tasksForTaskList = computed(() => {
+ // 通过条件判断访问触发器,确保折叠状态变化时重新计算
+ if (updateTaskTrigger.value >= 0) {
+ // 触发器起作用,继续执行计算逻辑
+ }
+
const result: Task[] = []
// 如果有里程碑,创建里程碑分组行(扁平化显示)
@@ -2004,6 +2017,9 @@ function handleTimelineEditTask(task: Task) {
function handleAddPredecessor(targetTask: Task) {
if (!targetTask) return
+ // 触发事件供外部使用
+ emit('add-predecessor', targetTask)
+
// 1. 记录要添加前置任务的目标任务
taskToAddPredecessorTo.value = targetTask
@@ -2036,6 +2052,10 @@ function handleAddPredecessor(targetTask: Task) {
// 处理添加后置任务事件
function handleAddSuccessor(targetTask: Task) {
if (!targetTask) return
+
+ // 触发事件供外部使用
+ emit('add-successor', targetTask)
+
// 记录要添加后置任务的目标任务
taskToAddSuccessorTo.value = targetTask
// 构造新任务,parentId 与目标任务一致,predecessor 仅包含目标任务 id
@@ -2063,6 +2083,18 @@ function handleAddSuccessor(targetTask: Task) {
taskDrawerVisible.value = true
}
+// 处理前置任务已添加事件(拖拽连接完成)
+function handlePredecessorAdded(event: { targetTask: Task; newTask: Task }) {
+ // 直接转发事件给外部
+ emit('predecessor-added', event)
+}
+
+// 处理后置任务已添加事件(拖拽连接完成)
+function handleSuccessorAdded(event: { targetTask: Task; newTask: Task }) {
+ // 直接转发事件给外部
+ emit('successor-added', event)
+}
+
// 新增Task插入到任务树中
// 插入新任务到任务树(parentId 已在打开 TaskDrawer 时预设好)
const insertTask = (tasks: Task[], newTask: Task) => {
@@ -2161,6 +2193,39 @@ function handleTaskDelete(task: Task, deleteChildren?: boolean) {
emit('task-deleted', { task })
}
+// 处理链接删除事件
+function handleLinkDeleted(event: {
+ sourceTaskId: number
+ targetTaskId: number
+ updatedTask: Task
+}) {
+ if (props.tasks) {
+ // 在 tasks 树中找到目标任务并更新
+ const updateTaskInTree = (taskList: Task[]): boolean => {
+ for (let i = 0; i < taskList.length; i++) {
+ if (taskList[i].id === event.targetTaskId) {
+ // 使用新对象替换,确保响应式更新
+ taskList[i] = { ...taskList[i], predecessor: event.updatedTask.predecessor }
+ return true
+ }
+ if (taskList[i].children && taskList[i].children!.length > 0) {
+ if (updateTaskInTree(taskList[i].children!)) {
+ return true
+ }
+ }
+ }
+ return false
+ }
+ updateTaskInTree(props.tasks)
+ }
+
+ // 触发任务更新事件
+ emit('task-updated', { task: event.updatedTask })
+
+ // 向外部发送链接删除事件
+ emit('link-deleted', event)
+}
+
// 处理里程碑双击事件
function handleMilestoneDoubleClick(milestone: Milestone) {
// 先触发外部事件,让外部可以自定义处理
@@ -2295,7 +2360,10 @@ function handleMilestoneDialogDelete(milestoneId: number) {
@stop-timer="handleStopTimer"
@add-predecessor="handleAddPredecessor"
@add-successor="handleAddSuccessor"
+ @predecessor-added="handlePredecessorAdded"
+ @successor-added="handleSuccessorAdded"
@delete="handleTaskDelete"
+ @link-deleted="handleLinkDeleted"
>
diff --git a/src/components/GanttConfirmDialog.vue b/src/components/GanttConfirmDialog.vue
index 48eef64..2390754 100644
--- a/src/components/GanttConfirmDialog.vue
+++ b/src/components/GanttConfirmDialog.vue
@@ -28,23 +28,23 @@ const onNo = () => emit('no')